diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 7bad2ca92c7..8c0b01a731a 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -93,12 +93,12 @@ jobs: - tokio-no-features - tokio-with-net -# # Try cross compiling -# - template: ci/azure-cross-compile.yml -# parameters: -# name: cross_32bit_linux -# target: i686-unknown-linux-gnu -# +# Try cross compiling +- template: ci/azure-cross-compile.yml + parameters: + name: cross + rust: $(nightly) + # # This represents the minimum Rust version supported by # # Tokio. Updating this should be done in a dedicated PR and # # cannot be greater than two 0.x releases prior to the @@ -127,6 +127,6 @@ jobs: - test_linux - test_features # - test_nightly -# - cross_32bit_linux + - cross # - minrust # - tsan diff --git a/ci/azure-cross-compile.yml b/ci/azure-cross-compile.yml index 8c2553c726d..f0e83f03162 100644 --- a/ci/azure-cross-compile.yml +++ b/ci/azure-cross-compile.yml @@ -1,27 +1,41 @@ jobs: - job: ${{ parameters.name }} displayName: ${{ parameters.displayName }} + strategy: + matrix: + i686: + vmImage: ubuntu-16.04 + target: i686-unknown-linux-gnu + powerpc: + vmImage: ubuntu-16.04 + target: powerpc-unknown-linux-gnu + powerpc64: + vmImage: ubuntu-16.04 + target: powerpc64-unknown-linux-gnu + mips: + vmImage: ubuntu-16.04 + target: mips-unknown-linux-gnu pool: - vmImage: ubuntu-16.04 + vmImage: $(vmImage) steps: - template: azure-install-rust.yml parameters: - rust_version: stable + rust_version: ${{ parameters.rust }} - script: sudo apt-get update - displayName: "apt-get update" + displayName: apt-get update - script: sudo apt-get install gcc-multilib - displayName: "Install gcc-multilib" + displayName: Install gcc-multilib - - script: rustup target add ${{ parameters.target }} - displayName: "Add target" + - script: cargo install cross + displayName: Install cross # Always patch - template: azure-patch-crates.yml - - script: cargo check --all --exclude tokio-tls --target ${{ parameters.target }} + - script: cross check --all --exclude tokio-tls --target $(target) displayName: Check source - - script: cargo check --tests --all --exclude tokio-tls --target ${{ parameters.target }} - displayName: Check tests + # - script: cross check --tests --all --exclude tokio-tls --target $(target) + # displayName: Check tests diff --git a/tokio-timer/src/atomic.rs b/tokio-timer/src/atomic.rs new file mode 100644 index 00000000000..6a592edb4aa --- /dev/null +++ b/tokio-timer/src/atomic.rs @@ -0,0 +1,59 @@ +//! Implementation of an atomic u64 cell. On 64 bit platforms, this is a +//! re-export of `AtomicU64`. On 32 bit platforms, this is implemented using a +//! `Mutex`. + +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")]`. +#[cfg(not(any(target_arch = "mips", target_arch = "powerpc")))] +mod imp { + pub(crate) use std::sync::atomic::AtomicU64; +} + +#[cfg(any(target_arch = "mips", target_arch = "powerpc"))] +mod imp { + use std::sync::atomic::Ordering; + use std::sync::Mutex; + + #[derive(Debug)] + pub(crate) struct AtomicU64 { + inner: Mutex, + } + + impl AtomicU64 { + pub(crate) fn new(val: u64) -> AtomicU64 { + AtomicU64 { + inner: Mutex::new(val), + } + } + + pub(crate) fn load(&self, _: Ordering) -> u64 { + *self.inner.lock().unwrap() + } + + pub(crate) fn store(&self, val: u64, _: Ordering) { + *self.inner.lock().unwrap() = val; + } + + pub(crate) fn fetch_or(&self, val: u64, _: Ordering) -> u64 { + let mut lock = self.inner.lock().unwrap(); + let prev = *lock; + *lock = prev | val; + prev + } + + pub(crate) fn compare_and_swap(&self, old: u64, new: u64, _: Ordering) -> u64 { + let mut lock = self.inner.lock().unwrap(); + let prev = *lock; + + if prev != old { + return prev; + } + + *lock = new; + prev + } + } +} diff --git a/tokio-timer/src/lib.rs b/tokio-timer/src/lib.rs index 943476664c8..04590d4b459 100644 --- a/tokio-timer/src/lib.rs +++ b/tokio-timer/src/lib.rs @@ -42,6 +42,7 @@ pub mod throttle; pub mod timeout; pub mod timer; +mod atomic; mod delay; mod error; mod interval; diff --git a/tokio-timer/src/timer/entry.rs b/tokio-timer/src/timer/entry.rs index 219d027b9ce..6d30f84c9ae 100644 --- a/tokio-timer/src/timer/entry.rs +++ b/tokio-timer/src/timer/entry.rs @@ -1,10 +1,11 @@ +use crate::atomic::AtomicU64; use crate::timer::{HandlePriv, Inner}; use crate::Error; use crossbeam_utils::CachePadded; use std::cell::UnsafeCell; use std::ptr; +use std::sync::atomic::AtomicBool; use std::sync::atomic::Ordering::{Relaxed, SeqCst}; -use std::sync::atomic::{AtomicBool, AtomicU64}; use std::sync::{Arc, Weak}; use std::task::{self, Poll}; use std::time::{Duration, Instant}; diff --git a/tokio-timer/src/timer/mod.rs b/tokio-timer/src/timer/mod.rs index 1a25ef0ac4c..ee384f15d1c 100644 --- a/tokio-timer/src/timer/mod.rs +++ b/tokio-timer/src/timer/mod.rs @@ -49,10 +49,11 @@ pub use self::handle::{set_default, Handle}; pub use self::now::{Now, SystemNow}; pub(crate) use self::registration::Registration; +use crate::atomic::AtomicU64; use crate::wheel; use crate::Error; +use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering::SeqCst; -use std::sync::atomic::{AtomicU64, AtomicUsize}; use std::sync::Arc; use std::time::{Duration, Instant}; use std::usize;