Merge pull request #413 from alistair23/alistair/atomics

atomics: Add support for targets without atomics
This commit is contained in:
Steven Fackler 2020-09-22 19:38:37 -04:00 committed by GitHub
commit 9a1902dfc6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 66 additions and 4 deletions

View File

@ -79,5 +79,6 @@ jobs:
run: |
rustup update stable --no-self-update
rustup default stable
- run: rustup target add thumbv6m-none-eabi
- run: rustup target add thumbv6m-none-eabi riscv32imc-unknown-none-elf
- run: cargo build --verbose --target=thumbv6m-none-eabi
- run: cargo build --verbose --target=riscv32imc-unknown-none-elf

View File

@ -20,11 +20,14 @@ fn main() {
None => return,
};
// If the target isn't thumbv6 then we can use atomic CAS
if !target.starts_with("thumbv6") {
if target_has_atomic_cas(&target) {
println!("cargo:rustc-cfg=atomic_cas");
}
if target_has_atomics(&target) {
println!("cargo:rustc-cfg=has_atomics");
}
// If the Rust version is at least 1.46.0 then we can use type ids at compile time
if minor >= 47 {
println!("cargo:rustc-cfg=const_type_id");
@ -38,6 +41,23 @@ fn main() {
println!("cargo:rerun-if-changed=build.rs");
}
fn target_has_atomic_cas(target: &str) -> bool {
match &target[..] {
"thumbv6m-none-eabi"
| "msp430-none-elf"
| "riscv32i-unknown-none-elf"
| "riscv32imc-unknown-none-elf" => false,
_ => true,
}
}
fn target_has_atomics(target: &str) -> bool {
match &target[..] {
"msp430-none-elf" | "riscv32i-unknown-none-elf" | "riscv32imc-unknown-none-elf" => false,
_ => true,
}
}
fn rustc_target() -> Option<String> {
env::var("TARGET").ok()
}

View File

@ -288,7 +288,6 @@ use std::error;
use std::fmt;
use std::mem;
use std::str::FromStr;
use std::sync::atomic::{AtomicUsize, Ordering};
#[macro_use]
mod macros;
@ -297,6 +296,48 @@ mod serde;
#[cfg(feature = "kv_unstable")]
pub mod kv;
#[cfg(has_atomics)]
use std::sync::atomic::{AtomicUsize, Ordering};
#[cfg(not(has_atomics))]
use std::cell::Cell;
#[cfg(not(has_atomics))]
use std::sync::atomic::Ordering;
#[cfg(not(has_atomics))]
struct AtomicUsize {
v: Cell<usize>,
}
#[cfg(not(has_atomics))]
impl AtomicUsize {
const fn new(v: usize) -> AtomicUsize {
AtomicUsize { v: Cell::new(v) }
}
fn load(&self, _order: Ordering) -> usize {
self.v.get()
}
fn store(&self, val: usize, _order: Ordering) {
self.v.set(val)
}
#[cfg(atomic_cas)]
fn compare_and_swap(&self, current: usize, new: usize, _order: Ordering) -> usize {
let prev = self.v.get();
if current == prev {
self.v.set(new);
}
prev
}
}
// Any platform without atomics is unlikely to have multiple cores, so
// writing via Cell will not be a race condition.
#[cfg(not(has_atomics))]
unsafe impl Sync for AtomicUsize {}
// The LOGGER static holds a pointer to the global logger. It is protected by
// the STATE static which determines whether LOGGER has been initialized yet.
static mut LOGGER: &dyn Log = &NopLogger;