Skip to content

Commit

Permalink
Add embassy multi-thread feature, use it in sunsetc
Browse files Browse the repository at this point in the history
Now sunsetc runs with a threaded executor instead of a LocalSet,
to test multi-thread.
  • Loading branch information
mkj committed Jun 16, 2024
1 parent 2805ce8 commit 53884ed
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 14 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions async/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,6 @@ embedded-io-adapters = { version = "0.6", features = ["tokio-1"] }
simplelog = "0.12"
# for simplelog
time = { version = "0.3", features = ["local-offset"] }

sunset-embassy = { version = "0.2", path = "../embassy", features = ["multi-thread"] }
critical-section = { version = "1.1", features = ["std"] }
16 changes: 7 additions & 9 deletions async/examples/sunsetc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,7 @@ use time::UtcOffset;
#[tokio::main]
async fn real_main(tz: UtcOffset) -> Result<()> {
let args = parse_args(tz)?;

// TODO: currently we just run it all on a single thread.
// Running with tokio's normal multiple threads works fine
// if we change SunsetRawMutex to a CriticalSectionMutex
// (or something wrapping std::sync::Mutex).
// Need to figure how to make it configurable.
let local = tokio::task::LocalSet::new();
let exit_code = local.run_until(run(args)).await?;
let exit_code = run(args).await?;
std::process::exit(exit_code)
}

Expand Down Expand Up @@ -73,11 +66,16 @@ async fn run(args: Args) -> Result<i32> {
want_pty = false
}

let ssh_task = spawn_local(async move {
// Sunset will work fine on a non-threaded executor (such as Tokio LocalSet).
// sunset-embassy's "multi-thread" feature is not required in that case.
// sunsetc example here uses the normal threaded scheduler in order to test the
// "multi-thread" feature (and as a more "default" example).
let ssh_task = tokio::task::spawn(async move {
let mut rxbuf = Zeroizing::new(vec![0; 3000]);
let mut txbuf = Zeroizing::new(vec![0; 3000]);
let ssh = SSHClient::new(&mut rxbuf, &mut txbuf)?;

// CmdlineClient implements the session logic for a commandline SSH client.
let mut app = CmdlineClient::new(
args.username.as_ref().unwrap(),
&args.host,
Expand Down
1 change: 1 addition & 0 deletions async/src/cmdline_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,7 @@ enum EscapeAction {
Suspend,
}

/// Handles ~. escape sequences in an interactive shell.
#[derive(Debug)]
enum Escaper {
Idle,
Expand Down
6 changes: 6 additions & 0 deletions embassy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ sunset = { version = "0.2.0", path = "../", features = ["embedded-io"] }
log = { version = "0.4" }

[features]
# Use a critical-section mutex to lock state. This feature must be enabled
# to run on executors that require futures to be Send (such as default Tokio).
# The application should depend on critical-section "std" feature.
# When multi-thread is disabled locking overhead is avoided.
multi-thread = []

# Remove any use of `unsafe`. This currently requires
# nightly and -Zpolonius (not ready yet)
try-polonius = []
10 changes: 5 additions & 5 deletions embassy/src/embassy_sunset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ use core::sync::atomic::AtomicBool;
use core::sync::atomic::Ordering::{Relaxed, SeqCst};

use embassy_sync::waitqueue::WakerRegistration;
use embassy_sync::blocking_mutex::raw::NoopRawMutex;
#[allow(unused_imports)]
use embassy_sync::blocking_mutex::raw::{NoopRawMutex,CriticalSectionRawMutex};
use embassy_sync::mutex::{Mutex, MutexGuard};
use embassy_sync::signal::Signal;
use embassy_futures::select::select;
Expand All @@ -23,11 +24,10 @@ use sunset::{error, ChanData, ChanHandle, ChanNum, Error, Result, Runner};
use sunset::config::MAX_CHANNELS;
use sunset::event::Event;

// For now we only support single-threaded executors.
// In future this could be behind a cfg to allow different
// RawMutex for std executors or other situations.
#[cfg(feature = "multi-thread")]
pub type SunsetRawMutex = CriticalSectionRawMutex;
#[cfg(not(feature = "multi-thread"))]
pub type SunsetRawMutex = NoopRawMutex;
// pub type SunsetRawMutex = CriticalSectionRawMutex;

pub type SunsetMutex<T> = Mutex<SunsetRawMutex, T>;

Expand Down

0 comments on commit 53884ed

Please sign in to comment.