Skip to content

Commit ad28053

Browse files
committed
Use our own AtomicU64 on targets with target_has_atomic less than 64
1 parent 87de4e1 commit ad28053

File tree

4 files changed

+84
-1
lines changed

4 files changed

+84
-1
lines changed

.github/workflows/ci.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,39 @@ jobs:
4646
command: test
4747
args: --all --features unstable
4848

49+
cross:
50+
name: Cross compile
51+
runs-on: ubuntu-latest
52+
strategy:
53+
matrix:
54+
target:
55+
- i686-unknown-linux-gnu
56+
- powerpc-unknown-linux-gnu
57+
- powerpc64-unknown-linux-gnu
58+
- mips-unknown-linux-gnu
59+
- arm-linux-androideabi
60+
61+
steps:
62+
- uses: actions/checkout@master
63+
64+
- name: Install nightly
65+
uses: actions-rs/toolchain@v1
66+
with:
67+
toolchain: nightly
68+
override: true
69+
70+
- name: Install cross
71+
run: cargo install cross
72+
73+
- name: check
74+
run: cross check --all --target ${{ matrix.target }}
75+
76+
- name: check unstable
77+
run: cross check --all --features unstable --target ${{ matrix.target }}
78+
79+
- name: test
80+
run: cross test --all --features unstable --target ${{ matrix.target }}
81+
4982
check_fmt_and_docs:
5083
name: Checking fmt and docs
5184
runs-on: ubuntu-latest

src/sync/atomic.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
pub(crate) use self::imp::AtomicU64;
2+
3+
// `AtomicU64` can only be used on targets with `target_has_atomic` is 64 or greater.
4+
// Once `cfg_target_has_atomic` feature is stable, we can replace it with
5+
// `#[cfg(target_has_atomic = "64")]`.
6+
// Refs: https://github.com/rust-lang/rust/tree/master/src/librustc_target
7+
#[cfg(not(any(target_arch = "arm", target_arch = "mips", target_arch = "powerpc")))]
8+
mod imp {
9+
pub(crate) use std::sync::atomic::AtomicU64;
10+
}
11+
12+
#[cfg(any(target_arch = "arm", target_arch = "mips", target_arch = "powerpc"))]
13+
mod imp {
14+
use std::sync::atomic::Ordering;
15+
use std::sync::Mutex;
16+
17+
#[derive(Debug)]
18+
pub(crate) struct AtomicU64(Mutex<u64>);
19+
20+
impl AtomicU64 {
21+
pub(crate) fn new(val: u64) -> Self {
22+
Self(Mutex::new(val))
23+
}
24+
25+
pub(crate) fn load(&self, _: Ordering) -> u64 {
26+
*self.0.lock().unwrap()
27+
}
28+
29+
pub(crate) fn fetch_add(&self, val: u64, _: Ordering) -> u64 {
30+
let mut lock = self.0.lock().unwrap();
31+
let prev = *lock;
32+
*lock = prev + val;
33+
prev
34+
}
35+
36+
pub(crate) fn fetch_sub(&self, val: u64, _: Ordering) -> u64 {
37+
let mut lock = self.0.lock().unwrap();
38+
let prev = *lock;
39+
*lock = prev - val;
40+
prev
41+
}
42+
}
43+
}

src/sync/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ pub use std::sync::{Arc, Weak};
181181
pub use mutex::{Mutex, MutexGuard};
182182
pub use rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard};
183183

184+
pub(crate) mod atomic;
184185
mod mutex;
185186
mod rwlock;
186187

src/task/spawn_blocking.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
use std::sync::atomic::{AtomicU64, Ordering};
1+
use std::sync::atomic::Ordering;
22
use std::thread;
33
use std::time::Duration;
44

55
use crossbeam_channel::{bounded, Receiver, Sender};
66
use once_cell::sync::Lazy;
77

8+
use crate::sync::atomic::AtomicU64;
89
use crate::task::{JoinHandle, Task};
910
use crate::utils::{abort_on_panic, random};
1011

@@ -51,6 +52,11 @@ where
5152

5253
const MAX_THREADS: u64 = 10_000;
5354

55+
#[cfg(any(target_arch = "arm", target_arch = "mips", target_arch = "powerpc"))]
56+
lazy_static! {
57+
static ref DYNAMIC_THREAD_COUNT: AtomicU64 = AtomicU64::new(0);
58+
}
59+
#[cfg(not(any(target_arch = "arm", target_arch = "mips", target_arch = "powerpc")))]
5460
static DYNAMIC_THREAD_COUNT: AtomicU64 = AtomicU64::new(0);
5561

5662
struct Pool {

0 commit comments

Comments
 (0)