lib: Implement AtomicUsize for platforms without atomics

Some platforms don't provide a AtomicUsize. Instead of just failing to
build with this error:

291 | use std::sync::atomic::{AtomicUsize, Ordering};
    |                         ^^^^^^^^^^^ no `AtomicUsize` in `sync::atomic`

let's instead add a fake AtomicUsize.

As the platform doesn't have atomics we can't implement an Atomic
version of AtomicUsize, so this version is not atomic. Any platform
without atomics is unlikely to have multiple cores, so this shouldn't be
a problem.

This is somewhat based on:
940d2e9d7f

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
Alistair Francis 2020-09-11 11:35:14 -07:00
parent 85b8a11565
commit 351ee33633
2 changed files with 48 additions and 1 deletions

View File

@ -31,6 +31,14 @@ fn main() {
}
};
match &target[..] {
"msp430-none-elf" | "riscv32i-unknown-none-elf" | "riscv32imc-unknown-none-elf" => {}
_ => {
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");

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,46 @@ 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
}
}
#[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;