diff --git a/Cargo.lock b/Cargo.lock index 0bf071abc..c5b577202 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4527,6 +4527,15 @@ dependencies = [ "riot-rs-boards", ] +[[package]] +name = "threading-dynamic-prios" +version = "0.1.0" +dependencies = [ + "portable-atomic", + "riot-rs", + "riot-rs-boards", +] + [[package]] name = "threading-lock" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 362e8e436..3dd96db7c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ members = [ "tests/gpio-interrupt-nrf", "tests/gpio-interrupt-stm32", "tests/i2c-controller", + "tests/threading-dynamic-prios", "tests/threading-lock", ] diff --git a/tests/laze.yml b/tests/laze.yml index 9e73d211c..c8792e3ff 100644 --- a/tests/laze.yml +++ b/tests/laze.yml @@ -4,4 +4,5 @@ subdirs: - gpio-interrupt-nrf - gpio-interrupt-stm32 - i2c-controller + - threading-dynamic-prios - threading-lock diff --git a/tests/threading-dynamic-prios/Cargo.toml b/tests/threading-dynamic-prios/Cargo.toml new file mode 100644 index 000000000..04eb4be68 --- /dev/null +++ b/tests/threading-dynamic-prios/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "threading-dynamic-prios" +version = "0.1.0" +authors = ["Elena Frank "] +edition.workspace = true +license.workspace = true +publish = false + +[dependencies] +riot-rs = { path = "../../src/riot-rs", features = ["threading"] } +riot-rs-boards = { path = "../../src/riot-rs-boards" } +portable-atomic = { workspace = true } diff --git a/tests/threading-dynamic-prios/laze.yml b/tests/threading-dynamic-prios/laze.yml new file mode 100644 index 000000000..2bc4a6805 --- /dev/null +++ b/tests/threading-dynamic-prios/laze.yml @@ -0,0 +1,5 @@ +apps: + - name: threading-dynamic-prios + selects: + - ?release + - sw/threading diff --git a/tests/threading-dynamic-prios/src/main.rs b/tests/threading-dynamic-prios/src/main.rs new file mode 100644 index 000000000..4b198038b --- /dev/null +++ b/tests/threading-dynamic-prios/src/main.rs @@ -0,0 +1,52 @@ +#![no_main] +#![no_std] +#![feature(type_alias_impl_trait)] +#![feature(used_with_arg)] + +use portable_atomic::{AtomicUsize, Ordering}; + +use riot_rs::thread::{RunqueueId, ThreadId}; + +static RUN_ORDER: AtomicUsize = AtomicUsize::new(0); + +static TEMP_THREAD1_PRIO: RunqueueId = RunqueueId::new(5); + +#[riot_rs::thread(autostart, priority = 2)] +fn thread0() { + let pid = riot_rs::thread::current_pid().unwrap(); + assert_eq!(riot_rs::thread::get_priority(pid), Some(RunqueueId::new(2))); + + assert_eq!(RUN_ORDER.fetch_add(1, Ordering::AcqRel), 0); + + let thread1_pid = ThreadId::new(1); + assert_eq!( + riot_rs::thread::get_priority(thread1_pid), + Some(RunqueueId::new(1)) + ); + riot_rs::thread::set_priority(thread1_pid, TEMP_THREAD1_PRIO); + + // thread1 runs now. + + assert_eq!(RUN_ORDER.fetch_add(1, Ordering::AcqRel), 2); + riot_rs::debug::log::info!("Test passed!"); + loop {} +} + +#[riot_rs::thread(autostart, priority = 1)] +fn thread1() { + // Thread can only run after thread0 increased its prio. + assert_eq!(RUN_ORDER.fetch_add(1, Ordering::AcqRel), 1); + // Prio is the temp increased prio. + let pid = riot_rs::thread::current_pid().unwrap(); + assert_eq!(riot_rs::thread::get_priority(pid), Some(TEMP_THREAD1_PRIO)); + // Other thread prios didn't change. + assert_eq!( + riot_rs::thread::get_priority(ThreadId::new(0)), + Some(RunqueueId::new(2)) + ); + + // Reset priority. + riot_rs::thread::set_priority(pid, RunqueueId::new(1)); + + unreachable!("Core should be blocked by higher prio thread.") +}