From aa9baa791b9d8b2b2e6ffb4608f2ab211009bc54 Mon Sep 17 00:00:00 2001 From: shuaihu Date: Thu, 7 Jul 2022 01:53:58 +0000 Subject: [PATCH 1/7] =?UTF-8?q?liteos=20=E4=B8=8B=E4=B8=8D=E8=83=BD?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E9=9B=86=E6=88=90=E6=B5=8B=E8=AF=95=EF=BC=8C?= =?UTF-8?q?=E5=85=A8=E9=83=A8=E6=B3=A8=E9=87=8A=E6=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .cargo/config.toml | 3 +++ .vscode/settings.json | 3 +++ Cargo.toml | 3 +++ examples/led.rs | 19 +++++++++++++++++++ examples/test_condvar.rs | 11 ++++++++++- examples/test_mutex.rs | 13 +++++++++++++ src/no_std/error.rs | 2 +- src/no_std/io/error.rs | 2 +- src/no_std/thread.rs | 2 +- 9 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 examples/led.rs diff --git a/.cargo/config.toml b/.cargo/config.toml index 055846d..a50fdf1 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -58,3 +58,6 @@ rustflags = [ "--cfg", 'LOS_PATH="../../stm32/LiteOS"', ] + +[build] +target="thumbv7m-none-eabi" \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..513cbeb --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "rust-analyzer.checkOnSave.allTargets": false +} \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 01449a6..d8692d0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,6 +36,9 @@ windows-sys = { version = "0.36.1", features = [ "Win32_System_SystemServices", ] } +[[example]] +name="led" +crate-type=["staticlib"] [profile.dev] panic = "abort" diff --git a/examples/led.rs b/examples/led.rs new file mode 100644 index 0000000..c6ed68c --- /dev/null +++ b/examples/led.rs @@ -0,0 +1,19 @@ +#![no_std] + +use stdlib::thread::{self}; + +extern "C" { + fn led_toggle(); +} +#[no_mangle] +extern "C" fn app_init() { + loop { + unsafe { led_toggle() }; + thread::sleep(1000); + } +} +#[cfg(not(test))] +#[panic_handler] +pub fn painc_handler(_info: &core::panic::PanicInfo<'_>) -> ! { + loop {} +} diff --git a/examples/test_condvar.rs b/examples/test_condvar.rs index ca45012..33a9a33 100644 --- a/examples/test_condvar.rs +++ b/examples/test_condvar.rs @@ -1,9 +1,18 @@ +#![cfg_attr(liteos, no_std)] + +extern crate alloc; +use alloc::string::ToString; + +#[no_mangle] +extern "C" fn app_init() { + main(); +} fn main() { use stdlib::thread::{self, *}; sleep(100); let a = Builder::new() - .name("asdf".to_owned()) + .name("asdf".to_string()) .stack_size(1024) .spawn(|| { thread::yield_now(); diff --git a/examples/test_mutex.rs b/examples/test_mutex.rs index 42dea28..608ac28 100644 --- a/examples/test_mutex.rs +++ b/examples/test_mutex.rs @@ -1,3 +1,13 @@ +#![cfg_attr(liteos, no_std)] + +extern crate alloc; + +#[no_mangle] +extern "C" fn app_init() { + main(); +} + +#[cfg(not(liteos))] fn main() { use stdlib::sync::Mutex; let mut mt = Mutex::new(0); @@ -16,3 +26,6 @@ fn main() { let v = mt.into_inner(); assert_eq!(v, 45); } + +#[cfg(liteos)] +fn main() {} diff --git a/src/no_std/error.rs b/src/no_std/error.rs index 6672773..f3eb5e6 100644 --- a/src/no_std/error.rs +++ b/src/no_std/error.rs @@ -1,4 +1,4 @@ -#[cfg(test)] +#[cfg(all(test,not(liteos)))] mod tests; use alloc::borrow::Cow; diff --git a/src/no_std/io/error.rs b/src/no_std/io/error.rs index 6006dd9..67d50f6 100644 --- a/src/no_std/io/error.rs +++ b/src/no_std/io/error.rs @@ -1,4 +1,4 @@ -#[cfg(test)] +#[cfg(all(test,not(liteos)))] mod tests; use core::{ fmt::{Debug, Display}, diff --git a/src/no_std/thread.rs b/src/no_std/thread.rs index 201880e..23f6f58 100644 --- a/src/no_std/thread.rs +++ b/src/no_std/thread.rs @@ -1,4 +1,4 @@ -#[cfg(test)] +#[cfg(all(test,not(liteos)))] mod tests; use crate::io::Result; use alloc::{boxed::Box, string::String, sync::Arc}; -- Gitee From 225e71781531c7eaec20021ab9a88455475f0ace Mon Sep 17 00:00:00 2001 From: shuaihu Date: Thu, 7 Jul 2022 01:59:18 +0000 Subject: [PATCH 2/7] =?UTF-8?q?=E5=B5=8C=E5=85=A5=E5=BC=8F=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E4=B8=8D=E6=94=AF=E6=8C=81=E9=9B=86=E6=88=90=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/no_std/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/no_std/error.rs b/src/no_std/error.rs index f3eb5e6..13ea387 100644 --- a/src/no_std/error.rs +++ b/src/no_std/error.rs @@ -1,4 +1,4 @@ -#[cfg(all(test,not(liteos)))] +#[cfg(all(test,not(target_os="none")))] mod tests; use alloc::borrow::Cow; -- Gitee From e4a01f2a1bdfdaa3c829760cb0078902ac7c467d Mon Sep 17 00:00:00 2001 From: shuaihu Date: Thu, 7 Jul 2022 01:59:47 +0000 Subject: [PATCH 3/7] =?UTF-8?q?=E5=B5=8C=E5=85=A5=E5=BC=8F=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E4=B8=8D=E6=94=AF=E6=8C=81=E9=9B=86=E6=88=90=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/no_std/io/error.rs | 2 +- src/no_std/thread.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/no_std/io/error.rs b/src/no_std/io/error.rs index 67d50f6..297671b 100644 --- a/src/no_std/io/error.rs +++ b/src/no_std/io/error.rs @@ -1,4 +1,4 @@ -#[cfg(all(test,not(liteos)))] +#[cfg(all(test,not(target_os="none")))] mod tests; use core::{ fmt::{Debug, Display}, diff --git a/src/no_std/thread.rs b/src/no_std/thread.rs index 23f6f58..a06fcd9 100644 --- a/src/no_std/thread.rs +++ b/src/no_std/thread.rs @@ -1,4 +1,4 @@ -#[cfg(all(test,not(liteos)))] +#[cfg(all(test,not(target_os="none")))] mod tests; use crate::io::Result; use alloc::{boxed::Box, string::String, sync::Arc}; -- Gitee From efa61fab7e9765493f4b5c6f03ff68f487f6dfa2 Mon Sep 17 00:00:00 2001 From: shuaihu Date: Mon, 11 Jul 2022 02:50:13 +0000 Subject: [PATCH 4/7] LedTest for LiteOS --- Cargo.toml | 17 ++++++++++++----- examples/led.rs | 4 +++- examples/test_condvar.rs | 15 ++++++++++++--- examples/test_mutex.rs | 31 ------------------------------- 4 files changed, 27 insertions(+), 40 deletions(-) delete mode 100644 examples/test_mutex.rs diff --git a/Cargo.toml b/Cargo.toml index d8692d0..5e4e662 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ alloc = ["arch"] std = ["parking"] [dependencies] -arch = { git = "https://gitee.com/iot-ua/arch.git", optional = true,branch ="develop"} +arch = { git = "https://gitee.com/iot-ua/arch.git", optional = true, branch = "develop" } parking = { version = "2.0.0", optional = true } cfg-if = "1.0.0" cache-padded = "1.2.0" @@ -37,10 +37,17 @@ windows-sys = { version = "0.36.1", features = [ ] } [[example]] -name="led" -crate-type=["staticlib"] +name = "led" +crate-type = ["staticlib"] + +[[example]] +name = "test_condvar" +crate-type = ["staticlib"] [profile.dev] -panic = "abort" + [profile.release] -panic = "abort" \ No newline at end of file +debug = false +lto = true +opt-level = 2 +codegen-units = 1 diff --git a/examples/led.rs b/examples/led.rs index c6ed68c..bdca1fa 100644 --- a/examples/led.rs +++ b/examples/led.rs @@ -1,12 +1,14 @@ #![no_std] - +#![feature(default_alloc_error_handler)] use stdlib::thread::{self}; extern "C" { fn led_toggle(); + fn DemoEntry(); } #[no_mangle] extern "C" fn app_init() { + unsafe { DemoEntry() }; loop { unsafe { led_toggle() }; thread::sleep(1000); diff --git a/examples/test_condvar.rs b/examples/test_condvar.rs index 33a9a33..c5dae2c 100644 --- a/examples/test_condvar.rs +++ b/examples/test_condvar.rs @@ -1,4 +1,4 @@ -#![cfg_attr(liteos, no_std)] +#![cfg_attr(liteos, no_std, feature(default_alloc_error_handler))] extern crate alloc; use alloc::string::ToString; @@ -7,16 +7,19 @@ use alloc::string::ToString; extern "C" fn app_init() { main(); } +extern "C" { + fn DemoEntry(); +} fn main() { use stdlib::thread::{self, *}; - + unsafe { DemoEntry() }; sleep(100); let a = Builder::new() .name("asdf".to_string()) .stack_size(1024) .spawn(|| { thread::yield_now(); - thread::sleep(100); + thread::sleep(100000); }) .unwrap(); @@ -29,3 +32,9 @@ fn main() { let f = b.join(); assert_eq!(f, 55); } + +#[cfg(not(test))] +#[panic_handler] +pub fn painc_handler(_info: &core::panic::PanicInfo<'_>) -> ! { + loop {} +} diff --git a/examples/test_mutex.rs b/examples/test_mutex.rs deleted file mode 100644 index 608ac28..0000000 --- a/examples/test_mutex.rs +++ /dev/null @@ -1,31 +0,0 @@ -#![cfg_attr(liteos, no_std)] - -extern crate alloc; - -#[no_mangle] -extern "C" fn app_init() { - main(); -} - -#[cfg(not(liteos))] -fn main() { - use stdlib::sync::Mutex; - let mut mt = Mutex::new(0); - let _abc = mt.get_mut(); - *_abc = 22; - let mut t = mt.lock(); - - *t = 45; - let tt = mt.try_lock(); - assert!(tt.is_none()); - drop(tt); - Mutex::unlock(t); - let tt = mt.try_lock(); - assert!(tt.is_some()); - drop(tt); - let v = mt.into_inner(); - assert_eq!(v, 45); -} - -#[cfg(liteos)] -fn main() {} -- Gitee From 6164d57b1569ebb692f65fc5d850802b5a1c8e3a Mon Sep 17 00:00:00 2001 From: shuaihu Date: Wed, 13 Jul 2022 07:42:37 +0000 Subject: [PATCH 5/7] LiteOS Mutex_Park --- .cargo/config.toml | 2 +- Cargo.toml | 19 +++++-- examples/{led.rs => led_liteos.rs} | 0 examples/{test_condvar.rs => mutex_liteos.rs} | 52 ++++++++----------- examples/parker_liteos.rs | 35 +++++++++++++ src/no_std/collections/objpool.rs | 4 +- src/no_std/mod.rs | 1 - src/no_std/sync/mod.rs | 13 ++++- src/no_std/thread.rs | 2 +- src/std/sync/parker.rs | 20 ++++--- 10 files changed, 100 insertions(+), 48 deletions(-) rename examples/{led.rs => led_liteos.rs} (100%) rename examples/{test_condvar.rs => mutex_liteos.rs} (30%) create mode 100644 examples/parker_liteos.rs diff --git a/.cargo/config.toml b/.cargo/config.toml index a50fdf1..15c932b 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -60,4 +60,4 @@ rustflags = [ ] [build] -target="thumbv7m-none-eabi" \ No newline at end of file +target = "thumbv7m-none-eabi" diff --git a/Cargo.toml b/Cargo.toml index 5e4e662..fcb81a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,15 +5,15 @@ version = "0.1.0" [lib] crate-type = ["rlib"] -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] default = ["alloc"] alloc = ["arch"] std = ["parking"] + [dependencies] -arch = { git = "https://gitee.com/iot-ua/arch.git", optional = true, branch = "develop" } +arch = { path = "../arch", optional = true } parking = { version = "2.0.0", optional = true } cfg-if = "1.0.0" cache-padded = "1.2.0" @@ -37,17 +37,26 @@ windows-sys = { version = "0.36.1", features = [ ] } [[example]] -name = "led" +name = "led_liteos" +crate-type = ["staticlib"] +required-features = ["alloc"] + +[[example]] +name = "mutex_liteos" crate-type = ["staticlib"] +required-features = ["alloc"] [[example]] -name = "test_condvar" +name = "parker_liteos" crate-type = ["staticlib"] +required-features = ["alloc"] [profile.dev] +panic = "abort" [profile.release] -debug = false +debug = true +panic = "abort" lto = true opt-level = 2 codegen-units = 1 diff --git a/examples/led.rs b/examples/led_liteos.rs similarity index 100% rename from examples/led.rs rename to examples/led_liteos.rs diff --git a/examples/test_condvar.rs b/examples/mutex_liteos.rs similarity index 30% rename from examples/test_condvar.rs rename to examples/mutex_liteos.rs index c5dae2c..5d2c7a5 100644 --- a/examples/test_condvar.rs +++ b/examples/mutex_liteos.rs @@ -1,38 +1,32 @@ -#![cfg_attr(liteos, no_std, feature(default_alloc_error_handler))] - +#![no_std] +#![feature(default_alloc_error_handler)] +use stdlib::{ + sync::Mutex, + thread::{self}, +}; extern crate alloc; -use alloc::string::ToString; - -#[no_mangle] -extern "C" fn app_init() { - main(); -} +use alloc::sync::Arc; extern "C" { + // fn led_toggle(); fn DemoEntry(); } -fn main() { - use stdlib::thread::{self, *}; +#[no_mangle] +extern "C" fn app_init() { unsafe { DemoEntry() }; - sleep(100); - let a = Builder::new() - .name("asdf".to_string()) - .stack_size(1024) - .spawn(|| { - thread::yield_now(); - thread::sleep(100000); - }) - .unwrap(); - - a.join(); - let b = thread::spawn(|| 55); - let _c = b.is_finished(); - let d = b.thread(); - let _e = d.name(); - - let f = b.join(); - assert_eq!(f, 55); + let mutex = Arc::new(Mutex::new(32)); + let thmutex = mutex.clone(); + let mut mm = mutex.lock(); + *mm = 35; + let th = thread::spawn(move || { + let mut mm = thmutex.lock(); + *mm = 46; + }); + thread::sleep(10000); + drop(mm); + th.join(); + let mm = mutex.lock(); + assert_eq!(*mm, 46); } - #[cfg(not(test))] #[panic_handler] pub fn painc_handler(_info: &core::panic::PanicInfo<'_>) -> ! { diff --git a/examples/parker_liteos.rs b/examples/parker_liteos.rs new file mode 100644 index 0000000..c8484de --- /dev/null +++ b/examples/parker_liteos.rs @@ -0,0 +1,35 @@ +#![no_std] +#![feature(default_alloc_error_handler)] +use stdlib::{ + sync::Parker, + thread::{self}, +}; +extern crate alloc; +use alloc::sync::Arc; +extern "C" { + fn led_toggle(); + fn DemoEntry(); +} +#[no_mangle] +unsafe extern "C" fn app_init() { + led_toggle(); + DemoEntry(); + let parker = Arc::new(Parker::new()); + let unparker = parker.clone(); + let th = thread::Builder::new() + .name("shuaihu\0".into()) + .stack_size(800) + .spawn_unchecked(move || { + parker.park(); + led_toggle(); + }) + .unwrap(); + thread::sleep(5000); + unparker.unpark(); + th.join(); +} +#[cfg(not(test))] +#[panic_handler] +pub fn painc_handler(_info: &core::panic::PanicInfo<'_>) -> ! { + loop {} +} diff --git a/src/no_std/collections/objpool.rs b/src/no_std/collections/objpool.rs index 37f9d75..f9cb096 100644 --- a/src/no_std/collections/objpool.rs +++ b/src/no_std/collections/objpool.rs @@ -1,5 +1,4 @@ use crate::sync::Parker; -use crate::thread; use alloc::alloc::{alloc, dealloc}; use core::{ alloc::Layout, @@ -391,8 +390,7 @@ mod test { .name(format!("thread-{}", i)) .stack_size(1024 * 1024) .spawn(move || { - let mut q: [Option>; 100] = - unsafe { core::mem::zeroed() }; + let mut q: [Option>; 100] = unsafe { core::mem::zeroed() }; for _ in 0..10 { for i in 0..20 { q[i] = Some(pool.get(TestDrop(10))); diff --git a/src/no_std/mod.rs b/src/no_std/mod.rs index 1d514c8..6a3b109 100644 --- a/src/no_std/mod.rs +++ b/src/no_std/mod.rs @@ -4,7 +4,6 @@ pub mod error; pub mod io; #[cfg(unix)] pub mod lazy; -#[cfg(unix)] pub mod sync; pub mod thread; #[macro_export] diff --git a/src/no_std/sync/mod.rs b/src/no_std/sync/mod.rs index d647b0c..58b8f3c 100644 --- a/src/no_std/sync/mod.rs +++ b/src/no_std/sync/mod.rs @@ -1,11 +1,20 @@ +#[cfg(unix)] mod condvar; +#[cfg(unix)] +pub use condvar::Condvar; + mod mutex; +pub use mutex::{Mutex, MutexGuard}; + +#[cfg(unix)] mod once; +#[cfg(unix)] mod rwlock; mod spinlock; pub use arch::locks::Parker; -pub use condvar::Condvar; -pub use mutex::{Mutex, MutexGuard}; + +#[cfg(unix)] pub use once::{Once, OnceState}; +#[cfg(unix)] pub use rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard}; pub use spinlock::*; diff --git a/src/no_std/thread.rs b/src/no_std/thread.rs index a06fcd9..9bc8ba7 100644 --- a/src/no_std/thread.rs +++ b/src/no_std/thread.rs @@ -1,4 +1,4 @@ -#[cfg(all(test,not(target_os="none")))] +#[cfg(all(test, not(target_os = "none")))] mod tests; use crate::io::Result; use alloc::{boxed::Box, string::String, sync::Arc}; diff --git a/src/std/sync/parker.rs b/src/std/sync/parker.rs index e253d32..cd3f7c8 100644 --- a/src/std/sync/parker.rs +++ b/src/std/sync/parker.rs @@ -1,7 +1,15 @@ -pub use parking::Parker; -#[test] -fn test() { - let park = Parker::new(); - park.park(); - park.unpark(); +pub struct Parker(parking::Parker); +impl Parker { + #[inline] + pub fn new() -> Self { + Self(parking::Parker::new()) + } + #[inline] + pub fn park(&self) { + self.0.park(); + } + #[inline] + pub fn unpark(&self) { + self.0.unpark(); + } } -- Gitee From 1e62641f41c01280ca507c1953d58233a3bd6b14 Mon Sep 17 00:00:00 2001 From: shuaihu Date: Thu, 14 Jul 2022 11:22:25 +0000 Subject: [PATCH 6/7] once+spinlock --- .cargo/config.toml | 4 +- .vscode/settings.json | 6 ++- src/no_std/sync/once.rs | 9 ++++ src/no_std/sync/once/tests.rs | 91 +++++++++++++++++++++++++++++++++++ 4 files changed, 107 insertions(+), 3 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index 15c932b..5ce8985 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -59,5 +59,5 @@ rustflags = [ 'LOS_PATH="../../stm32/LiteOS"', ] -[build] -target = "thumbv7m-none-eabi" +# [build] +# target = "thumbv7m-none-eabi" diff --git a/.vscode/settings.json b/.vscode/settings.json index 513cbeb..f8243c2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,7 @@ { - "rust-analyzer.checkOnSave.allTargets": false + "rust-analyzer.checkOnSave.allTargets": false, + "lldb.displayFormat": "auto", + "lldb.showDisassembly": "auto", + "lldb.dereferencePointers": true, + "lldb.consoleMode": "commands" } \ No newline at end of file diff --git a/src/no_std/sync/once.rs b/src/no_std/sync/once.rs index 3fdf398..65dd17b 100644 --- a/src/no_std/sync/once.rs +++ b/src/no_std/sync/once.rs @@ -1,6 +1,8 @@ #[cfg(test)] mod tests; +use arch::os::CPU_CORE_NUMBERS; + use crate::sync::Parker; use crate::thread::{self, Thread}; use core::cell::Cell; @@ -163,9 +165,16 @@ impl Once { fn wait(state_and_queue: &AtomicPtr, mut current_state: *mut Masked) { // Note: the following code was carefully written to avoid creating a // mutable reference to `node` that gets aliased. + let mut cnt: usize = 1000; loop { // Don't queue this thread if the status is no longer running, // otherwise we will not be woken up. + if CPU_CORE_NUMBERS > 1 && current_state.addr() & STATE_MASK == RUNNING && cnt > 0 { + current_state = state_and_queue.load(Ordering::Acquire); + cnt -= 1; + core::hint::spin_loop(); + continue; + } if current_state.addr() & STATE_MASK != RUNNING { return; } diff --git a/src/no_std/sync/once/tests.rs b/src/no_std/sync/once/tests.rs index e69de29..8bd95e8 100644 --- a/src/no_std/sync/once/tests.rs +++ b/src/no_std/sync/once/tests.rs @@ -0,0 +1,91 @@ + +extern crate std; +use std::sync::mpsc::channel; +use super::Once; +use std::panic; +use crate::thread; +#[test] +fn smoke_once() { + static O: Once = Once::new(); + let mut a = 0; + O.call_once(|| a += 1); + assert_eq!(a, 1); + O.call_once(|| a += 1); + assert_eq!(a, 1); +} +#[test] +fn stampede_once() { + static O: Once = Once::new(); + static mut RUN: bool = false; + + let (tx, rx) = channel(); + for _ in 0..100 { + let tx = tx.clone(); + thread::spawn(move || { + for _ in 0..4 { + thread::yield_now() + } + unsafe { + O.call_once(|| { + assert!(!RUN); + RUN = true; + }); + assert!(RUN); + } + tx.send(()).unwrap(); + }); + } + + unsafe { + O.call_once(|| { + assert!(!RUN); + RUN = true; + }); + assert!(RUN); + } + + for _ in 0..10 { + rx.recv().unwrap(); + } +} + + +#[test] +fn wait_for_force_to_finish() { + static O: Once = Once::new(); + + // poison the once + let t = panic::catch_unwind(|| { + O.call_once(|| panic!()); + }); + assert!(t.is_err()); + + // make sure someone's waiting inside the once via a force + let (tx1, rx1) = channel(); + let (tx2, rx2) = channel(); + let t1 = thread::spawn(move || { + O.call_once_force(|p| { + assert!(p.is_poisoned()); + tx1.send(()).unwrap(); + rx2.recv().unwrap(); + }); + true + }); + + rx1.recv().unwrap(); + + // put another waiter on the once + let t2 = thread::spawn(|| { + let mut called = false; + O.call_once(|| { + called = true; + }); + assert!(!called); + true + }); + + tx2.send(()).unwrap(); + + assert!(t1.join()); + assert!(t2.join()); +} -- Gitee From fbec00ff14620d5ca63bee9c918ac50155e90017 Mon Sep 17 00:00:00 2001 From: shuaihu Date: Fri, 22 Jul 2022 10:01:02 +0000 Subject: [PATCH 7/7] Parker+Mutex+const Mutex --- .cargo/config.toml | 19 +++--- .gitignore | 1 + .vscode/settings.json | 5 +- .vscode/tasks.json | 17 +++++ Cargo.toml | 39 ++++++----- build.rs | 35 ++++++++++ examples/led_liteos.rs | 21 ------ examples/liteos/mod.rs | 4 ++ examples/{mutex_liteos.rs => liteos/mutex.rs} | 22 +------ examples/liteos/parker.rs | 47 +++++++++++++ examples/parker_liteos.rs | 35 ---------- examples/test_liteos.rs | 44 +++++++++++++ src/lib.rs | 9 +++ src/no_std/collections/objpool.rs | 66 +------------------ src/no_std/collections/objpool/tests.rs | 56 ++++++++++++++++ src/no_std/collections/unbounded.rs | 2 +- src/no_std/mod.rs | 21 +++--- src/no_std/sync/mod.rs | 7 +- src/no_std/sync/mutex.rs | 17 ++--- src/no_std/sync/mutex/tests.rs | 39 +++++++++++ src/no_std/sync/once.rs | 9 +-- src/no_std/sync/once/tests.rs | 8 +-- src/no_std/sync/parker.rs | 1 + src/no_std/sync/spinlock.rs | 8 ++- src/std/sync/condvar.rs | 2 +- src/std/sync/mod.rs | 3 +- src/std/sync/mutex.rs | 2 +- src/std/sync/parker.rs | 18 +++++ 28 files changed, 350 insertions(+), 207 deletions(-) create mode 100644 .vscode/tasks.json create mode 100644 build.rs delete mode 100644 examples/led_liteos.rs create mode 100644 examples/liteos/mod.rs rename examples/{mutex_liteos.rs => liteos/mutex.rs} (48%) create mode 100644 examples/liteos/parker.rs delete mode 100644 examples/parker_liteos.rs create mode 100644 examples/test_liteos.rs create mode 100644 src/no_std/collections/objpool/tests.rs create mode 100644 src/no_std/sync/parker.rs diff --git a/.cargo/config.toml b/.cargo/config.toml index 5ce8985..f00fc80 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,5 +1,5 @@ # Mircrosoft Visual Studio 目标配置(ARM平台不需要) -[target.x86_64-pc-windows-msvc.arch] +[target.x86_64-pc-windows-msvc] rustflags = [ # +crt_static Indicates a static connection to the C runtime library # -crt_static Indicates dynamic connection to the C runtime library @@ -32,14 +32,7 @@ rustflags = [ "WIN10", ] -[nightly-x86_64-unknown-linux-gnu] -rustflags = [ - # Designated as win10 system. Some functions of the system below win10 cannot be used. - "--cfg", - "WIN10", -] - -[x86_64-unknown-linux-gnu] +[target.x86_64-unknown-linux-gnu] rustflags = [ # Designated as win10 system. Some functions of the system below win10 cannot be used. "--cfg", @@ -56,8 +49,12 @@ rustflags = [ 'target_os="liteos_m"', # Specify LiteOS location "--cfg", - 'LOS_PATH="../../stm32/LiteOS"', + 'LOS_PATH="../../../c/LiteOS"', + "--cfg", + "single_thread", ] -# [build] +[build] +# target = "x86_64-pc-windows-msvc" +target = "x86_64-unknown-linux-gnu" # target = "thumbv7m-none-eabi" diff --git a/.gitignore b/.gitignore index 4fffb2f..40c0b10 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target /Cargo.lock +src/sysinfo.rs diff --git a/.vscode/settings.json b/.vscode/settings.json index f8243c2..9232241 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,8 @@ { - "rust-analyzer.checkOnSave.allTargets": false, "lldb.displayFormat": "auto", "lldb.showDisassembly": "auto", "lldb.dereferencePointers": true, - "lldb.consoleMode": "commands" + "lldb.consoleMode": "commands", + "editor.formatOnPaste": true, + "editor.formatOnSave": true } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..013c2af --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,17 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "type": "cargo", + "command": "build", + "args": [ + "--examples" + ], + "problemMatcher": [ + "$rustc" + ], + "group": "build", + "label": "build stdlib stdlib" + } + ] +} \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index fcb81a8..eeb4eab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,11 +13,16 @@ std = ["parking"] [dependencies] -arch = { path = "../arch", optional = true } +utils = { git = "https://gitee.com/iot-ua/utils.git", branch = "develop" } +arch = { git = "https://gitee.com/iot-ua/arch.git", branch = "develop", optional = true } parking = { version = "2.0.0", optional = true } cfg-if = "1.0.0" cache-padded = "1.2.0" +[build-dependencies] +regex = "1.5.6" +num_cpus = "1.13.1" + [target.'cfg(unix)'.dev-dependencies] libc = { version = "0.2.126", default-features = false } @@ -37,26 +42,28 @@ windows-sys = { version = "0.36.1", features = [ ] } [[example]] -name = "led_liteos" -crate-type = ["staticlib"] -required-features = ["alloc"] - -[[example]] -name = "mutex_liteos" -crate-type = ["staticlib"] -required-features = ["alloc"] - -[[example]] -name = "parker_liteos" +name = "test_liteos" crate-type = ["staticlib"] required-features = ["alloc"] [profile.dev] -panic = "abort" +opt-level = 2 +debug = true +rpath = false +lto = false +debug-assertions = false +codegen-units = 1 +panic = 'abort' +incremental = false +overflow-checks = false [profile.release] -debug = true -panic = "abort" +opt-level = 3 +debug = false +rpath = false lto = true -opt-level = 2 +debug-assertions = false codegen-units = 1 +panic = 'abort' +incremental = false +overflow-checks = false diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..fa3a283 --- /dev/null +++ b/build.rs @@ -0,0 +1,35 @@ +use std::{env, ffi::OsStr, fs::File, io::Write, path::PathBuf, str::FromStr}; +fn main() { + //当前构建文件所在位置 + let manifest_path = env::var("CARGO_MANIFEST_DIR").unwrap(); + let manifest_path = PathBuf::from_str(&manifest_path).unwrap(); + //根据项目输入位置,推导项目根文件夹实质位置。 + let out_dir = env::var("OUT_DIR").unwrap(); + let out_path = PathBuf::from_str(&out_dir).unwrap(); + let mut top_path = PathBuf::new(); + for i in out_path.iter() { + if i == OsStr::new("target") { + break; + } + top_path.push(i); + } + //是否配置位置LITEOS,详细参见编译配置文件 ".cargo/config.toml 中的编译选项: "--cfg", "liteos" + if env::var("CARGO_CFG_LITEOS").is_err() { + let mut fcfg = File::options() + .write(true) + .create(true) + .truncate(true) + .open(manifest_path.join("src/sysinfo.rs")) + .unwrap(); + let cpus = num_cpus::get(); + + write!(fcfg,"//The following content is automatically generated by the compiler.\n//please do not modify it.\n").unwrap(); + + write!(fcfg, "pub const CPU_CORE_NUMBERS: usize = {}usize;", cpus).unwrap(); + } + println!("cargo:rerun-if-changed=build.rs"); + println!( + "cargo:rerun-if-changed={}", + top_path.join(".cargo/config.toml").to_str().unwrap() + ); +} diff --git a/examples/led_liteos.rs b/examples/led_liteos.rs deleted file mode 100644 index bdca1fa..0000000 --- a/examples/led_liteos.rs +++ /dev/null @@ -1,21 +0,0 @@ -#![no_std] -#![feature(default_alloc_error_handler)] -use stdlib::thread::{self}; - -extern "C" { - fn led_toggle(); - fn DemoEntry(); -} -#[no_mangle] -extern "C" fn app_init() { - unsafe { DemoEntry() }; - loop { - unsafe { led_toggle() }; - thread::sleep(1000); - } -} -#[cfg(not(test))] -#[panic_handler] -pub fn painc_handler(_info: &core::panic::PanicInfo<'_>) -> ! { - loop {} -} diff --git a/examples/liteos/mod.rs b/examples/liteos/mod.rs new file mode 100644 index 0000000..29eca78 --- /dev/null +++ b/examples/liteos/mod.rs @@ -0,0 +1,4 @@ +mod parker; +pub use parker::*; +mod mutex; +pub use mutex::*; diff --git a/examples/mutex_liteos.rs b/examples/liteos/mutex.rs similarity index 48% rename from examples/mutex_liteos.rs rename to examples/liteos/mutex.rs index 5d2c7a5..70124c3 100644 --- a/examples/mutex_liteos.rs +++ b/examples/liteos/mutex.rs @@ -1,18 +1,7 @@ -#![no_std] -#![feature(default_alloc_error_handler)] -use stdlib::{ - sync::Mutex, - thread::{self}, -}; -extern crate alloc; use alloc::sync::Arc; -extern "C" { - // fn led_toggle(); - fn DemoEntry(); -} -#[no_mangle] -extern "C" fn app_init() { - unsafe { DemoEntry() }; +use stdlib::sync::Mutex; +use stdlib::thread; +pub fn mutex_test() { let mutex = Arc::new(Mutex::new(32)); let thmutex = mutex.clone(); let mut mm = mutex.lock(); @@ -27,8 +16,3 @@ extern "C" fn app_init() { let mm = mutex.lock(); assert_eq!(*mm, 46); } -#[cfg(not(test))] -#[panic_handler] -pub fn painc_handler(_info: &core::panic::PanicInfo<'_>) -> ! { - loop {} -} diff --git a/examples/liteos/parker.rs b/examples/liteos/parker.rs new file mode 100644 index 0000000..a60f2f7 --- /dev/null +++ b/examples/liteos/parker.rs @@ -0,0 +1,47 @@ +use stdlib::{println, sync::parker::*, thread}; + +pub fn park_timeout_unpark_before() { + let p = Parker::new(); + for _ in 0..10 { + p.unparker().unpark(); + p.park_timeout(u32::MAX); + } +} + +pub fn park_timeout_unpark_not_called() { + let p = Parker::new(); + for _ in 0..10 { + p.park_timeout(10); + } +} + +pub fn park_timeout_unpark_called_other_thread() { + for _ in 0..5 { + let p = Parker::new(); + let u = p.unparker(); + thread::spawn(move || { + thread::sleep(50); + u.unpark(); + }); + thread::spawn(move || { + p.park_timeout(u32::MAX); + }); + } +} + +pub fn parker_driver_led() { + let (p, u) = pair(); + thread::spawn(move || { + for _ in 0..10 { + p.park(); + unsafe { + crate::led_toggle(); + println!("Ok!"); + }; + } + }); + for _ in 0..10 { + thread::sleep(500); + u.unpark(); + } +} diff --git a/examples/parker_liteos.rs b/examples/parker_liteos.rs deleted file mode 100644 index c8484de..0000000 --- a/examples/parker_liteos.rs +++ /dev/null @@ -1,35 +0,0 @@ -#![no_std] -#![feature(default_alloc_error_handler)] -use stdlib::{ - sync::Parker, - thread::{self}, -}; -extern crate alloc; -use alloc::sync::Arc; -extern "C" { - fn led_toggle(); - fn DemoEntry(); -} -#[no_mangle] -unsafe extern "C" fn app_init() { - led_toggle(); - DemoEntry(); - let parker = Arc::new(Parker::new()); - let unparker = parker.clone(); - let th = thread::Builder::new() - .name("shuaihu\0".into()) - .stack_size(800) - .spawn_unchecked(move || { - parker.park(); - led_toggle(); - }) - .unwrap(); - thread::sleep(5000); - unparker.unpark(); - th.join(); -} -#[cfg(not(test))] -#[panic_handler] -pub fn painc_handler(_info: &core::panic::PanicInfo<'_>) -> ! { - loop {} -} diff --git a/examples/test_liteos.rs b/examples/test_liteos.rs new file mode 100644 index 0000000..cd15257 --- /dev/null +++ b/examples/test_liteos.rs @@ -0,0 +1,44 @@ +#![no_std] +#![feature(default_alloc_error_handler)] +#![feature(panic_info_message)] + +#[allow(unused_imports)] +#[macro_use] +extern crate alloc; +use alloc::string::ToString; +use stdlib::println; + +#[allow(unused)] +extern "C" { + fn led_toggle(); + fn DemoEntry(); +} + +// #[cfg(not(test))] +#[panic_handler] +pub fn painc_handler(info: &core::panic::PanicInfo<'_>) -> ! { + let s = info.to_string(); + println!("{}", s); + loop {} +} + +mod liteos; +use liteos::*; +#[no_mangle] +unsafe extern "C" fn app_init() { + DemoEntry(); + println!("-----------------------------------------"); + println!("{}", "Test park_timeout_unpark_before start..."); + park_timeout_unpark_before(); + println!("{}", "Test park_timeout_unpark_not_called start..."); + park_timeout_unpark_not_called(); + println!( + "{}", + "Test park_timeout_unpark_called_other_thread start..." + ); + park_timeout_unpark_called_other_thread(); + println!("{}", "Test parker_driver_led start..."); + parker_driver_led(); + println!("{}", "Test Mutex start..."); + mutex_test(); +} diff --git a/src/lib.rs b/src/lib.rs index 9949093..65b34bc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,6 +33,8 @@ #![feature(once_cell)] #![feature(dropck_eyepatch)] #![feature(stmt_expr_attributes)] +#![feature(atomic_mut_ptr)] +#![feature(let_chains)] #[cfg(all(feature = "std", feature = "alloc"))] compile_error!("std and alloc features cannot be enabled at same time."); @@ -47,10 +49,17 @@ cfg_if! { mod std; pub use crate::std::*; pub mod anyhow; + mod sysinfo; + pub mod os{ + pub use super::sysinfo::CPU_CORE_NUMBERS; + } }else if #[cfg(all(feature="alloc",not(feature="std")))]{ #[allow(unused_imports)] mod no_std; pub use no_std::*; pub mod anyhow; + pub mod os{ + pub const CPU_CORE_NUMBERS:usize=arch::os::CPU_CORE_NUMBERS; + } } } diff --git a/src/no_std/collections/objpool.rs b/src/no_std/collections/objpool.rs index f9cb096..ba21022 100644 --- a/src/no_std/collections/objpool.rs +++ b/src/no_std/collections/objpool.rs @@ -1,4 +1,6 @@ -use crate::sync::Parker; +#[cfg(all(test, not(target_os = "none")))] +mod tests; +use crate::sync::parker::Parker; use alloc::alloc::{alloc, dealloc}; use core::{ alloc::Layout, @@ -348,65 +350,3 @@ impl Drop for ObjPool { } } } - -#[cfg(test)] -mod test { - - use super::Obj; - use alloc::format; - use alloc::sync::Arc; - use alloc::vec::Vec; - use core::mem::MaybeUninit; - struct TestDrop(usize); - impl Drop for TestDrop { - fn drop(&mut self) { - // println!("Droped\n\0"); - } - } - impl Default for TestDrop { - fn default() -> Self { - Self(0) - } - } - use crate::thread; - - use super::ObjPool; - - static POOL: ObjPool = ObjPool::new(); - - #[test] - fn test_new() { - for _ in 0..50000 { - let pool = Arc::new(ObjPool::::new()); - let mut threads = Vec::new(); - let c = unsafe { POOL.get_uninit() }; - let m = unsafe { c.as_mut() }; - m.0 = 44; - drop(c); - - for i in 0..8 { - let pool = pool.clone(); - let th = thread::Builder::new() - .name(format!("thread-{}", i)) - .stack_size(1024 * 1024) - .spawn(move || { - let mut q: [Option>; 100] = unsafe { core::mem::zeroed() }; - for _ in 0..10 { - for i in 0..20 { - q[i] = Some(pool.get(TestDrop(10))); - let i = q[i].as_ref().take().unwrap(); - unsafe { i.as_mut().0 = 55 }; - } - } - }) - .unwrap(); - threads.push(th); - } - - for th in threads.drain(..) { - th.join(); - } - } - assert_eq!(1, 1); - } -} diff --git a/src/no_std/collections/objpool/tests.rs b/src/no_std/collections/objpool/tests.rs new file mode 100644 index 0000000..e909de3 --- /dev/null +++ b/src/no_std/collections/objpool/tests.rs @@ -0,0 +1,56 @@ +use super::Obj; +use alloc::format; +use alloc::sync::Arc; +use alloc::vec::Vec; +struct TestDrop(usize); +impl Drop for TestDrop { + fn drop(&mut self) { + // println!("Droped\n\0"); + } +} +impl Default for TestDrop { + fn default() -> Self { + Self(0) + } +} +use crate::thread; + +use super::ObjPool; + +static POOL: ObjPool = ObjPool::new(); + +#[test] +fn test_new() { + for _ in 0..50000 { + let pool = Arc::new(ObjPool::::new()); + let mut threads = Vec::new(); + let c = unsafe { POOL.get_uninit() }; + let m = unsafe { c.as_mut() }; + m.0 = 44; + drop(c); + + for i in 0..8 { + let pool = pool.clone(); + let th = thread::Builder::new() + .name(format!("thread-{}", i)) + .stack_size(1024 * 1024) + .spawn(move || { + let mut q: [Option>; 100] = unsafe { core::mem::zeroed() }; + for _ in 0..10 { + for i in 0..20 { + q[i] = Some(pool.get(TestDrop(10))); + let i = q[i].as_ref().take().unwrap(); + unsafe { i.as_mut().0 = 55 }; + } + } + }) + .unwrap(); + threads.push(th); + } + + for th in threads.drain(..) { + th.join(); + } + } + assert_eq!(1, 1); +} diff --git a/src/no_std/collections/unbounded.rs b/src/no_std/collections/unbounded.rs index 973e2b2..bf82f33 100644 --- a/src/no_std/collections/unbounded.rs +++ b/src/no_std/collections/unbounded.rs @@ -1,4 +1,4 @@ -#[cfg(test)] +#[cfg(all(test, not(target_os = "none")))] mod tests; use crate::thread; use alloc::boxed::Box; diff --git a/src/no_std/mod.rs b/src/no_std/mod.rs index 6a3b109..df94624 100644 --- a/src/no_std/mod.rs +++ b/src/no_std/mod.rs @@ -1,17 +1,20 @@ -#[cfg(unix)] pub mod collections; pub mod error; pub mod io; -#[cfg(unix)] pub mod lazy; pub mod sync; pub mod thread; -#[macro_export] -macro_rules! println { +pub use arch::os::printf; +pub macro println{ () => { - //TODO 实现平台相关的打印输出。 - }; - ($($arg:tt)*) => { - //TODO 实现平台相关的打印输出。 - }; + unsafe{ $crate::printf("\n\0") } + }, + ($fmt:tt)=>{ + let s=concat!($fmt,"\n\0"); + unsafe{ $crate::printf(s.as_ptr().cast()) } + }, + ($fmt:tt,$($arg:tt)*) => { + let s= alloc::format!(core::concat!($fmt, "\n\0"),$($arg)*); + unsafe{ $crate::printf(s.as_ptr().cast()) } + } } diff --git a/src/no_std/sync/mod.rs b/src/no_std/sync/mod.rs index 58b8f3c..472756d 100644 --- a/src/no_std/sync/mod.rs +++ b/src/no_std/sync/mod.rs @@ -1,19 +1,18 @@ #[cfg(unix)] mod condvar; + #[cfg(unix)] pub use condvar::Condvar; - +#[allow(dead_code)] mod mutex; pub use mutex::{Mutex, MutexGuard}; -#[cfg(unix)] mod once; +pub mod parker; #[cfg(unix)] mod rwlock; mod spinlock; -pub use arch::locks::Parker; -#[cfg(unix)] pub use once::{Once, OnceState}; #[cfg(unix)] pub use rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard}; diff --git a/src/no_std/sync/mutex.rs b/src/no_std/sync/mutex.rs index 3d739d7..c07e670 100644 --- a/src/no_std/sync/mutex.rs +++ b/src/no_std/sync/mutex.rs @@ -1,4 +1,4 @@ -#[cfg(test)] +#[cfg(all(test, not(target_os = "none")))] mod tests; use arch::locks::MovableMutex as imp; use core::cell::UnsafeCell; @@ -6,10 +6,9 @@ use core::ops::Deref; use core::ops::DerefMut; pub(super) struct MovableMutex(imp); impl MovableMutex { - fn new() -> Self { - let mut m = imp::from(arch::locks::Mutex::new()); - unsafe { m.init() }; - Self(m) + #[inline] + const fn new() -> Self { + Self(imp::new()) } pub(super) fn raw(&self) -> &imp { &self.0 @@ -27,12 +26,6 @@ impl MovableMutex { self.0.unlock() } } -impl Drop for MovableMutex { - #[inline] - fn drop(&mut self) { - unsafe { self.0.destroy() }; - } -} pub struct Mutex { inner: MovableMutex, @@ -41,7 +34,7 @@ pub struct Mutex { unsafe impl Send for Mutex {} unsafe impl Sync for Mutex {} impl Mutex { - pub fn new(t: T) -> Mutex { + pub const fn new(t: T) -> Mutex { Mutex { inner: MovableMutex::new(), data: UnsafeCell::new(t), diff --git a/src/no_std/sync/mutex/tests.rs b/src/no_std/sync/mutex/tests.rs index 8b13789..3aa8041 100644 --- a/src/no_std/sync/mutex/tests.rs +++ b/src/no_std/sync/mutex/tests.rs @@ -1 +1,40 @@ +extern crate std; +use crate::sync::mutex::Mutex; +use crate::thread; +use std::sync::mpsc::channel; +use std::sync::Arc; +#[test] +fn lots_and_lots() { + const J: u32 = 1000; + const K: u32 = 3; + let m = Arc::new(Mutex::new(0)); + + fn inc(m: &Mutex) { + for _ in 0..J { + *m.lock() += 1; + } + } + + let (tx, rx) = channel(); + for _ in 0..K { + let tx2 = tx.clone(); + let m2 = m.clone(); + thread::spawn(move || { + inc(&m2); + tx2.send(()).unwrap(); + }); + let tx2 = tx.clone(); + let m2 = m.clone(); + thread::spawn(move || { + inc(&m2); + tx2.send(()).unwrap(); + }); + } + + drop(tx); + for _ in 0..2 * K { + rx.recv().unwrap(); + } + assert_eq!(*m.lock(), J * K * 2); +} diff --git a/src/no_std/sync/once.rs b/src/no_std/sync/once.rs index 65dd17b..ccfe028 100644 --- a/src/no_std/sync/once.rs +++ b/src/no_std/sync/once.rs @@ -1,9 +1,10 @@ -#[cfg(test)] +#[cfg(all(test, not(target_os = "none")))] mod tests; +use arch::locks::parker::*; + use arch::os::CPU_CORE_NUMBERS; -use crate::sync::Parker; use crate::thread::{self, Thread}; use core::cell::Cell; use core::fmt; @@ -165,7 +166,7 @@ impl Once { fn wait(state_and_queue: &AtomicPtr, mut current_state: *mut Masked) { // Note: the following code was carefully written to avoid creating a // mutable reference to `node` that gets aliased. - let mut cnt: usize = 1000; + let mut cnt = 1000i32; loop { // Don't queue this thread if the status is no longer running, // otherwise we will not be woken up. @@ -210,7 +211,7 @@ fn wait(state_and_queue: &AtomicPtr, mut current_state: *mut Masked) { // can park ourselves, the result could be this thread never gets // unparked. Luckily `park` comes with the guarantee that if it got // an `unpark` just before on an unparked thread it does not park. - unsafe { node.parker.park() }; + node.parker.park(); } break; } diff --git a/src/no_std/sync/once/tests.rs b/src/no_std/sync/once/tests.rs index 8bd95e8..bed344c 100644 --- a/src/no_std/sync/once/tests.rs +++ b/src/no_std/sync/once/tests.rs @@ -1,9 +1,8 @@ - -extern crate std; -use std::sync::mpsc::channel; +extern crate std; use super::Once; -use std::panic; use crate::thread; +use std::panic; +use std::sync::mpsc::channel; #[test] fn smoke_once() { static O: Once = Once::new(); @@ -49,7 +48,6 @@ fn stampede_once() { } } - #[test] fn wait_for_force_to_finish() { static O: Once = Once::new(); diff --git a/src/no_std/sync/parker.rs b/src/no_std/sync/parker.rs new file mode 100644 index 0000000..fd6927c --- /dev/null +++ b/src/no_std/sync/parker.rs @@ -0,0 +1 @@ +pub use arch::locks::parker::*; diff --git a/src/no_std/sync/spinlock.rs b/src/no_std/sync/spinlock.rs index 7970950..6f16974 100644 --- a/src/no_std/sync/spinlock.rs +++ b/src/no_std/sync/spinlock.rs @@ -1,3 +1,5 @@ +use crate::os::CPU_CORE_NUMBERS; +use crate::thread::yield_now; use core::{ cell::UnsafeCell, hint::spin_loop, @@ -37,7 +39,11 @@ impl Spinlock { self.lock .compare_exchange(false, true, Ordering::AcqRel, Ordering::Acquire) { - spin_loop(); + if CPU_CORE_NUMBERS > 1 { + spin_loop(); + } else { + yield_now(); + } } } pub fn lock(&self) -> SpinlockGuard { diff --git a/src/std/sync/condvar.rs b/src/std/sync/condvar.rs index d91d424..b22a1e5 100644 --- a/src/std/sync/condvar.rs +++ b/src/std/sync/condvar.rs @@ -11,7 +11,7 @@ pub struct Condvar(imp); impl Condvar { #[must_use] #[inline] - pub fn new() -> Condvar { + pub const fn new() -> Condvar { Condvar(imp::new()) } diff --git a/src/std/sync/mod.rs b/src/std/sync/mod.rs index 2a7fce9..00d0b9c 100644 --- a/src/std/sync/mod.rs +++ b/src/std/sync/mod.rs @@ -7,6 +7,5 @@ pub use rwlock::*; #[path = "../../no_std/sync/spinlock.rs"] mod spinlock; pub use spinlock::*; -mod parker; -pub use parker::*; +pub mod parker; pub use std::sync::{Once, OnceState}; diff --git a/src/std/sync/mutex.rs b/src/std/sync/mutex.rs index ddc6af0..346e6c6 100644 --- a/src/std/sync/mutex.rs +++ b/src/std/sync/mutex.rs @@ -6,7 +6,7 @@ pub use std::sync::MutexGuard; pub struct Mutex(imp); impl Mutex { - pub fn new(t: T) -> Mutex { + pub const fn new(t: T) -> Mutex { Self(imp::new(t)) } } diff --git a/src/std/sync/parker.rs b/src/std/sync/parker.rs index cd3f7c8..c5610b3 100644 --- a/src/std/sync/parker.rs +++ b/src/std/sync/parker.rs @@ -1,4 +1,9 @@ +use core::time::Duration; + +use crate::std::ExtDuration; + pub struct Parker(parking::Parker); +pub use parking::Unparker; impl Parker { #[inline] pub fn new() -> Self { @@ -9,7 +14,20 @@ impl Parker { self.0.park(); } #[inline] + pub fn park_timeout(&self, ms: u32) -> bool { + self.0.park_timeout(Duration::saturating_from_millisec(ms)) + } + #[inline] pub fn unpark(&self) { self.0.unpark(); } + #[inline] + pub fn unparker(&self) -> Unparker { + self.0.unparker() + } +} +pub fn pair() -> (Parker, Unparker) { + let p = Parker::new(); + let u = p.unparker(); + (p, u) } -- Gitee