From 4630ec0b4a3df5109c712d574925983dc3e92053 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Mon, 7 Oct 2019 18:20:28 +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 | 39 ++++++++++++++++++++++++++++++++ src/sync/mod.rs | 1 + src/task/blocking.rs | 13 +++++++++-- src/task/task.rs | 13 +++++++++-- 5 files changed, 97 insertions(+), 17 deletions(-) create mode 100644 src/sync/atomic.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 55c32e744..6c3169faf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,22 +18,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 + + 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: tests - uses: actions-rs/cargo@v1 + - name: Install nightly + uses: actions-rs/toolchain@v1 with: - command: test - args: --all --doc --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..56ab630dc --- /dev/null +++ b/src/sync/atomic.rs @@ -0,0 +1,39 @@ +// `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_if::cfg_if! { + if #[cfg(not(any(target_arch = "arm", target_arch = "mips", target_arch = "powerpc")))] { + pub(crate) use std::sync::atomic::AtomicU64; + } else { + 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 df1d71ab3..cf77a4b20 100644 --- a/src/sync/mod.rs +++ b/src/sync/mod.rs @@ -38,6 +38,7 @@ pub use barrier::{Barrier, BarrierWaitResult}; pub use mutex::{Mutex, MutexGuard}; pub use rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard}; +pub(crate) mod atomic; #[cfg(any(feature = "unstable", feature = "docs"))] #[cfg_attr(feature = "docs", doc(cfg(unstable)))] mod barrier; diff --git a/src/task/blocking.rs b/src/task/blocking.rs index 41177bc93..e430dc733 100644 --- a/src/task/blocking.rs +++ b/src/task/blocking.rs @@ -2,7 +2,7 @@ use std::fmt; use std::pin::Pin; -use std::sync::atomic::{AtomicU64, Ordering}; +use std::sync::atomic::Ordering; use std::thread; use std::time::Duration; @@ -10,12 +10,21 @@ use crossbeam_channel::{bounded, Receiver, Sender}; use lazy_static::lazy_static; use crate::future::Future; +use crate::sync::atomic::AtomicU64; use crate::task::{Context, Poll}; use crate::utils::abort_on_panic; const MAX_THREADS: u64 = 10_000; -static DYNAMIC_THREAD_COUNT: AtomicU64 = AtomicU64::new(0); +cfg_if::cfg_if! { + if #[cfg(any(target_arch = "arm", target_arch = "mips", target_arch = "powerpc"))] { + lazy_static! { + static ref DYNAMIC_THREAD_COUNT: AtomicU64 = AtomicU64::new(0); + } + } else { + static DYNAMIC_THREAD_COUNT: AtomicU64 = AtomicU64::new(0); + } +} struct Pool { sender: Sender>, diff --git a/src/task/task.rs b/src/task/task.rs index 8a1addea4..a98688829 100644 --- a/src/task/task.rs +++ b/src/task/task.rs @@ -3,11 +3,12 @@ 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::future::Future; +use crate::sync::atomic::AtomicU64; use crate::task::{Context, Poll}; /// A handle to a task. @@ -112,7 +113,15 @@ pub struct TaskId(NonZeroU64); impl TaskId { pub(crate) fn new() -> TaskId { - static COUNTER: AtomicU64 = AtomicU64::new(1); + cfg_if::cfg_if! { + if #[cfg(any(target_arch = "arm", target_arch = "mips", target_arch = "powerpc"))] { + lazy_static::lazy_static! { + static ref COUNTER: AtomicU64 = AtomicU64::new(1); + } + } else { + static COUNTER: AtomicU64 = AtomicU64::new(1); + } + } let id = COUNTER.fetch_add(1, Ordering::Relaxed);