From d0074c3eaccc73970821f881d972fa4985e46958 Mon Sep 17 00:00:00 2001 From: dragon-zhang Date: Sat, 4 Jan 2025 10:23:26 +0800 Subject: [PATCH] pass almost all preemptive CI on unix --- .github/workflows/ci.yml | 2 +- core/docs/en/monitor.md | 6 ++--- core/src/common/macros.rs | 42 ++++++++++++++++----------------- core/src/coroutine/suspender.rs | 29 +++++++++++------------ 4 files changed, 39 insertions(+), 40 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e09a5e51..9833d5da 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,7 +55,7 @@ jobs: PROJECT_DIR: ${{ github.workspace }} run: sh .github/workflows/ci.sh - name: Run preemptive tests - if: ${{ contains(fromJSON('["x86_64-unknown-linux-gnu", "i686-unknown-linux-gnu", "x86_64-apple-darwin", "aarch64-apple-darwin"]'), matrix.target) }} + if: ${{ contains(matrix.os, 'ubuntu') && !contains(matrix.target, 'loongarch64') || contains(matrix.os, 'macos') }} env: CHANNEL: ${{ matrix.channel }} CROSS: ${{ !startsWith(matrix.target, 'x86_64') && contains(matrix.target, 'linux') && '1' || '0' }} diff --git a/core/docs/en/monitor.md b/core/docs/en/monitor.md index 99f304e6..cb459139 100644 --- a/core/docs/en/monitor.md +++ b/core/docs/en/monitor.md @@ -14,9 +14,9 @@ The `preemptive` feature currently supports the following targets: |---------------|-----------------------------------|--------------------------|---------| | `x86_64` | ✅ | ✅ | ❌ | | `x86` | ✅ | ❌ | ❌ | -| `AArch64` | ⚠️ | ✅ | ❌ | -| `ARM` | ⚠️ | ❌ | ❌ | -| `RISC-V` | ⚠️ | ❌ | ❌ | +| `AArch64` | ✅ | ✅ | ❌ | +| `ARM` | ✅ | ❌ | ❌ | +| `RISC-V` | ✅ | ❌ | ❌ | | `LoongArch64` | ⚠️ | ❌ | ❌ | ✅ Tested and stable; ⚠️ Tested but unstable; ❌ Not supported. diff --git a/core/src/common/macros.rs b/core/src/common/macros.rs index 4d1d62ef..b55eae87 100644 --- a/core/src/common/macros.rs +++ b/core/src/common/macros.rs @@ -88,21 +88,21 @@ macro_rules! impl_current_for { $struct_name:ident$(<$($generic:tt $( : $trait_tt1: tt $( + $trait_tt2: tt)*)?),+>)? ) => { thread_local! { - static $name: std::cell::RefCell> = - const { std::cell::RefCell::new(std::collections::VecDeque::new()) }; + static $name: crossbeam_utils::atomic::AtomicCell> = + const { crossbeam_utils::atomic::AtomicCell::new(std::collections::VecDeque::new()) }; } impl$(<$($generic $( : $trait_tt1 $( + $trait_tt2)*)?),+>)? $struct_name$(<$($generic),+>)? { /// Init the current. pub(crate) fn init_current(current: &Self) { - $name.with(|s| { - s.try_borrow_mut() - .unwrap_or_else(|e| { + $name.with(|s| unsafe { + s.as_ptr() + .as_mut() + .unwrap_or_else(|| { panic!( - "thread:{} init {} current failed with {}", + "thread:{} init {} current failed", std::thread::current().name().unwrap_or("unknown"), - stringify!($name), - e + stringify!($name) ) }) .push_front(core::ptr::from_ref(current).cast::()); @@ -113,31 +113,31 @@ macro_rules! impl_current_for { #[must_use] #[allow(unreachable_pub)] pub fn current<'current>() -> Option<&'current Self> { - $name.with(|s| { - s.try_borrow() - .unwrap_or_else(|e| { + $name.with(|s| unsafe { + s.as_ptr() + .as_ref() + .unwrap_or_else(|| { panic!( - "thread:{} get {} current failed with {}", + "thread:{} get {} current failed", std::thread::current().name().unwrap_or("unknown"), - stringify!($name), - e + stringify!($name) ) }) .front() - .map(|ptr| unsafe { &*(*ptr).cast::() }) + .map(|ptr| &*(*ptr).cast::()) }) } /// Clean the current. pub(crate) fn clean_current() { - $name.with(|s| { - _ = s.try_borrow_mut() - .unwrap_or_else(|e| { + $name.with(|s| unsafe { + _ = s.as_ptr() + .as_mut() + .unwrap_or_else(|| { panic!( - "thread:{} clean {} current failed with {}", + "thread:{} clean {} current failed", std::thread::current().name().unwrap_or("unknown"), - stringify!($name), - e + stringify!($name) ) }) .pop_front(); diff --git a/core/src/coroutine/suspender.rs b/core/src/coroutine/suspender.rs index d6e8d33d..ea5f2308 100644 --- a/core/src/coroutine/suspender.rs +++ b/core/src/coroutine/suspender.rs @@ -1,12 +1,11 @@ use crate::common::get_timeout_time; use crate::impl_current_for; -use std::cell::RefCell; -use std::collections::VecDeque; use std::time::Duration; thread_local! { #[allow(clippy::missing_const_for_thread_local)] - static TIMESTAMP: RefCell> = const { RefCell::new(VecDeque::new()) }; + static TIMESTAMP: crossbeam_utils::atomic::AtomicCell> = + const { crossbeam_utils::atomic::AtomicCell::new(std::collections::VecDeque::new()) }; } impl Suspender<'_, Param, Yield> { @@ -17,13 +16,13 @@ impl Suspender<'_, Param, Yield> { /// Delay the execution of the coroutine with an arg until `timestamp`. pub fn until_with(&self, arg: Yield, timestamp: u64) -> Param { - TIMESTAMP.with(|s| { - s.try_borrow_mut() - .unwrap_or_else(|e| { + TIMESTAMP.with(|s| unsafe { + s.as_ptr() + .as_mut() + .unwrap_or_else(|| { panic!( - "thread:{} init TIMESTAMP current failed with {}", - std::thread::current().name().unwrap_or("unknown"), - e + "thread:{} init TIMESTAMP current failed", + std::thread::current().name().unwrap_or("unknown") ) }) .push_front(timestamp); @@ -33,13 +32,13 @@ impl Suspender<'_, Param, Yield> { pub(crate) fn timestamp() -> u64 { TIMESTAMP - .with(|s| { - s.try_borrow_mut() - .unwrap_or_else(|e| { + .with(|s| unsafe { + s.as_ptr() + .as_mut() + .unwrap_or_else(|| { panic!( - "thread:{} get TIMESTAMP current failed with {}", - std::thread::current().name().unwrap_or("unknown"), - e + "thread:{} get TIMESTAMP current failed", + std::thread::current().name().unwrap_or("unknown") ) }) .pop_front()