Skip to content

Commit

Permalink
Merge pull request #325 from jonas-schievink/thumbv6
Browse files Browse the repository at this point in the history
Thumbv6 support
  • Loading branch information
sfackler committed Mar 28, 2019
2 parents b782a88 + 0f4bdaa commit 75043f9
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 1 deletion.
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ rust:
- stable
- beta
- nightly
install:
- '[ "$TRAVIS_RUST_VERSION" == "1.16.0" ] || rustup target add thumbv6m-none-eabi'
script:
- cargo build --verbose
- cargo build --verbose --features serde
- cargo build --verbose --features std
- '[ "$TRAVIS_RUST_VERSION" == "1.16.0" ] || cargo build --verbose --target=thumbv6m-none-eabi'
- cargo test --verbose
- cargo test --verbose --features serde
- cargo test --verbose --features std
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ A lightweight logging facade for Rust
categories = ["development-tools::debugging"]
keywords = ["logging"]
exclude = ["rfcs/**/*", "/.travis.yml", "/appveyor.yml"]
build = "build.rs"

[package.metadata.docs.rs]
features = ["std", "serde"]
Expand Down
14 changes: 14 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//! This build script detects target platforms that lack proper support for
//! atomics and sets `cfg` flags accordingly.

use std::env;

fn main() {
let target = env::var("TARGET").unwrap();

if !target.starts_with("thumbv6") {
println!("cargo:rustc-cfg=atomic_cas");
}

println!("cargo:rerun-if-changed=build.rs");
}
47 changes: 46 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1102,7 +1102,7 @@ pub fn max_level() -> LevelFilter {
/// An error is returned if a logger has already been set.
///
/// [`set_logger`]: fn.set_logger.html
#[cfg(feature = "std")]
#[cfg(all(feature = "std", atomic_cas))]
pub fn set_boxed_logger(logger: Box<Log>) -> Result<(), SetLoggerError> {
set_logger_inner(|| unsafe { &*Box::into_raw(logger) })
}
Expand All @@ -1116,6 +1116,13 @@ pub fn set_boxed_logger(logger: Box<Log>) -> Result<(), SetLoggerError> {
/// implementations should provide an initialization method that installs the
/// logger internally.
///
/// # Availability
///
/// This method is available even when the `std` feature is disabled. However,
/// it is currently unavailable on `thumbv6` targets, which lack support for
/// some atomic operations which are used by this function. Even on those
/// targets, [`set_logger_racy`] will be available.
///
/// # Errors
///
/// An error is returned if a logger has already been set.
Expand Down Expand Up @@ -1154,10 +1161,14 @@ pub fn set_boxed_logger(logger: Box<Log>) -> Result<(), SetLoggerError> {
/// error!("oops");
/// # }
/// ```
///
/// [`set_logger_racy`]: fn.set_logger_racy.html
#[cfg(atomic_cas)]
pub fn set_logger(logger: &'static Log) -> Result<(), SetLoggerError> {
set_logger_inner(|| logger)
}

#[cfg(atomic_cas)]
fn set_logger_inner<F>(make_logger: F) -> Result<(), SetLoggerError>
where
F: FnOnce() -> &'static Log,
Expand All @@ -1178,6 +1189,40 @@ where
}
}

/// A thread-unsafe version of [`set_logger`].
///
/// This function is available on all platforms, even those that do not have
/// support for atomics that is needed by [`set_logger`].
///
/// In almost all cases, [`set_logger`] should be preferred.
///
/// # Safety
///
/// This function is only safe to call when no other logger initialization
/// function is called while this function still executes.
///
/// This can be upheld by (for example) making sure that **there are no other
/// threads**, and (on embedded) that **interrupts are disabled**.
///
/// It is safe to use other logging functions while this function runs
/// (including all logging macros).
///
/// [`set_logger`]: fn.set_logger.html
pub unsafe fn set_logger_racy(logger: &'static Log) -> Result<(), SetLoggerError> {
match STATE.load(Ordering::SeqCst) {
UNINITIALIZED => {
LOGGER = logger;
STATE.store(INITIALIZED, Ordering::SeqCst);
Ok(())
}
INITIALIZING => {
// This is just plain UB, since we were racing another initialization function
unreachable!("set_logger_racy must not be used with other initialization functions")
}
_ => Err(SetLoggerError(())),
}
}

/// The type returned by [`set_logger`] if [`set_logger`] has already been called.
///
/// [`set_logger`]: fn.set_logger.html
Expand Down

0 comments on commit 75043f9

Please sign in to comment.