From 83487dac2753bf5b674c7bed1459518cd9cfec5e Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Fri, 18 Oct 2019 14:00:45 +0900 Subject: [PATCH] Use our own AtomicU64 on targets with target_has_atomic less than 64 --- .github/workflows/ci.yml | 48 +++++++++++++++++++++++++++++----------- src/sync/atomic.rs | 43 +++++++++++++++++++++++++++++++++++ src/sync/mod.rs | 1 + src/task/blocking.rs | 8 ++++++- src/task/task.rs | 8 ++++++- 5 files changed, 93 insertions(+), 15 deletions(-) create mode 100644 src/sync/atomic.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c622a59bf..90e85c4a6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,22 +26,44 @@ jobs: override: true - name: check - uses: actions-rs/cargo@v1 - with: - command: check - args: --all --benches --bins --examples --tests + run: | + cargo check --all --benches --bins --examples --tests + cargo check --features unstable --all --benches --bins --examples --tests - - name: check unstable - uses: actions-rs/cargo@v1 - with: - command: check - args: --features unstable --all --benches --bins --examples --tests + - name: test + run: cargo test --all --features unstable - - name: tests - uses: actions-rs/cargo@v1 + cross: + name: Cross compile + runs-on: ubuntu-latest + strategy: + matrix: + target: + - i686-unknown-linux-gnu + - powerpc-unknown-linux-gnu + - powerpc64-unknown-linux-gnu + - mips-unknown-linux-gnu + - arm-linux-androideabi + + steps: + - uses: actions/checkout@master + + - name: Install nightly + uses: actions-rs/toolchain@v1 with: - command: test - args: --all --features unstable + toolchain: nightly + override: true + + - name: Install cross + run: cargo install cross + + - name: check + run: | + cross check --all --target ${{ matrix.target }} + cross check --all --features unstable --target ${{ matrix.target }} + + - name: test + run: cross test --all --features unstable --target ${{ matrix.target }} check_fmt_and_docs: name: Checking fmt and docs diff --git a/src/sync/atomic.rs b/src/sync/atomic.rs new file mode 100644 index 000000000..75f69806e --- /dev/null +++ b/src/sync/atomic.rs @@ -0,0 +1,43 @@ +pub(crate) use self::imp::AtomicU64; + +// `AtomicU64` can only be used on targets with `target_has_atomic` is 64 or greater. +// Once `cfg_target_has_atomic` feature is stable, we can replace it with +// `#[cfg(target_has_atomic = "64")]`. +// Refs: https://github.com/rust-lang/rust/tree/master/src/librustc_target +#[cfg(not(any(target_arch = "arm", target_arch = "mips", target_arch = "powerpc")))] +mod imp { + pub(crate) use std::sync::atomic::AtomicU64; +} + +#[cfg(any(target_arch = "arm", target_arch = "mips", target_arch = "powerpc"))] +mod imp { + use std::sync::atomic::Ordering; + use std::sync::Mutex; + + #[derive(Debug)] + pub(crate) struct AtomicU64(Mutex); + + impl AtomicU64 { + pub(crate) fn new(val: u64) -> Self { + Self(Mutex::new(val)) + } + + pub(crate) fn load(&self, _: Ordering) -> u64 { + *self.0.lock().unwrap() + } + + pub(crate) fn fetch_add(&self, val: u64, _: Ordering) -> u64 { + let mut lock = self.0.lock().unwrap(); + let prev = *lock; + *lock = prev + val; + prev + } + + pub(crate) fn fetch_sub(&self, val: u64, _: Ordering) -> u64 { + let mut lock = self.0.lock().unwrap(); + let prev = *lock; + *lock = prev - val; + prev + } + } +} diff --git a/src/sync/mod.rs b/src/sync/mod.rs index be74d8f7b..822c088bd 100644 --- a/src/sync/mod.rs +++ b/src/sync/mod.rs @@ -35,6 +35,7 @@ pub use std::sync::{Arc, Weak}; pub use mutex::{Mutex, MutexGuard}; pub use rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard}; +pub(crate) mod atomic; mod mutex; mod rwlock; diff --git a/src/task/blocking.rs b/src/task/blocking.rs index 3216012a7..84ba3d130 100644 --- a/src/task/blocking.rs +++ b/src/task/blocking.rs @@ -1,17 +1,23 @@ //! A thread pool for running blocking functions asynchronously. -use std::sync::atomic::{AtomicU64, Ordering}; +use std::sync::atomic::Ordering; use std::thread; use std::time::Duration; use crossbeam_channel::{bounded, Receiver, Sender}; use lazy_static::lazy_static; +use crate::sync::atomic::AtomicU64; use crate::task::task::{JoinHandle, Tag}; use crate::utils::abort_on_panic; const MAX_THREADS: u64 = 10_000; +#[cfg(any(target_arch = "arm", target_arch = "mips", target_arch = "powerpc"))] +lazy_static! { + static ref DYNAMIC_THREAD_COUNT: AtomicU64 = AtomicU64::new(0); +} +#[cfg(not(any(target_arch = "arm", target_arch = "mips", target_arch = "powerpc")))] static DYNAMIC_THREAD_COUNT: AtomicU64 = AtomicU64::new(0); struct Pool { diff --git a/src/task/task.rs b/src/task/task.rs index ca3cac142..2ad1b5019 100644 --- a/src/task/task.rs +++ b/src/task/task.rs @@ -4,10 +4,11 @@ use std::i64; use std::mem; use std::num::NonZeroU64; use std::pin::Pin; -use std::sync::atomic::{AtomicU64, AtomicUsize, Ordering}; +use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; use super::task_local; +use crate::sync::atomic::AtomicU64; use crate::task::{Context, Poll}; /// A handle to a task. @@ -112,6 +113,11 @@ pub struct TaskId(NonZeroU64); impl TaskId { pub(crate) fn new() -> TaskId { + #[cfg(any(target_arch = "arm", target_arch = "mips", target_arch = "powerpc"))] + lazy_static::lazy_static! { + static ref COUNTER: AtomicU64 = AtomicU64::new(1); + } + #[cfg(not(any(target_arch = "arm", target_arch = "mips", target_arch = "powerpc")))] static COUNTER: AtomicU64 = AtomicU64::new(1); let id = COUNTER.fetch_add(1, Ordering::Relaxed);