-
Notifications
You must be signed in to change notification settings - Fork 754
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
core: vendor lazy_static and spin for no_std support (#424)
Following the suggested fix on #365: #365 (comment) tracing-core's use of `spin` is feature-gated. `lazy_static` is vendored for either feature but I've modified it to respect our feature flags. I've also removed doc comments that no longer compile and suppressed a couple of warnings with the lints that are now being applied. At this point * Including this in another project with std `lazy_static` works * Tracing unit tests pass both with and without `--no-default-features` Fixes #365 * core: vendor lazy_static and spin for no_std support * core: fmt vendored code * core: trim down vendored spin, reduce visibility and addresss warnings * core: limit vendored lazy_static for use only with no_std, fix warnings * core: update paths to now-vendored no_std libs * tracing: use spin::Once re-exported from tracing-core instead of crate * core: remove ineffectual doc(hidden) * core: refmt stdlib module * core: bump to 0.1.8 to expose export of vendored spin::Once to tracing
- Loading branch information
Showing
12 changed files
with
458 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
|
||
Copyright (c) 2010 The Rust Project Developers | ||
|
||
Permission is hereby granted, free of charge, to any | ||
person obtaining a copy of this software and associated | ||
documentation files (the "Software"), to deal in the | ||
Software without restriction, including without | ||
limitation the rights to use, copy, modify, merge, | ||
publish, distribute, sublicense, and/or sell copies of | ||
the Software, and to permit persons to whom the Software | ||
is furnished to do so, subject to the following | ||
conditions: | ||
|
||
The above copyright notice and this permission notice | ||
shall be included in all copies or substantial portions | ||
of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF | ||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED | ||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A | ||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT | ||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR | ||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
DEALINGS IN THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// Copyright 2016 lazy-static.rs Developers | ||
// | ||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or | ||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or | ||
// http://opensource.org/licenses/MIT>, at your option. This file may not be | ||
// copied, modified, or distributed except according to those terms. | ||
|
||
use crate::Once; | ||
|
||
pub(crate) struct Lazy<T: Sync>(Once<T>); | ||
|
||
impl<T: Sync> Lazy<T> { | ||
pub(crate) const INIT: Self = Lazy(Once::INIT); | ||
|
||
#[inline(always)] | ||
pub(crate) fn get<F>(&'static self, builder: F) -> &T | ||
where | ||
F: FnOnce() -> T, | ||
{ | ||
self.0.call_once(builder) | ||
} | ||
} | ||
|
||
#[macro_export] | ||
#[doc(hidden)] | ||
macro_rules! __lazy_static_create { | ||
($NAME:ident, $T:ty) => { | ||
static $NAME: $crate::lazy_static::lazy::Lazy<$T> = $crate::lazy_static::lazy::Lazy::INIT; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
// Copyright 2016 lazy-static.rs Developers | ||
// | ||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or | ||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or | ||
// http://opensource.org/licenses/MIT>, at your option. This file may not be | ||
// copied, modified, or distributed except according to those terms. | ||
|
||
/*! | ||
A macro for declaring lazily evaluated statics. | ||
Using this macro, it is possible to have `static`s that require code to be | ||
executed at runtime in order to be initialized. | ||
This includes anything requiring heap allocations, like vectors or hash maps, | ||
as well as anything that requires function calls to be computed. | ||
*/ | ||
|
||
#[path = "core_lazy.rs"] | ||
pub(crate) mod lazy; | ||
|
||
#[doc(hidden)] | ||
pub(crate) use core::ops::Deref as __Deref; | ||
|
||
#[macro_export(local_inner_macros)] | ||
#[doc(hidden)] | ||
macro_rules! __lazy_static_internal { | ||
// optional visibility restrictions are wrapped in `()` to allow for | ||
// explicitly passing otherwise implicit information about private items | ||
($(#[$attr:meta])* ($($vis:tt)*) static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => { | ||
__lazy_static_internal!(@MAKE TY, $(#[$attr])*, ($($vis)*), $N); | ||
__lazy_static_internal!(@TAIL, $N : $T = $e); | ||
lazy_static!($($t)*); | ||
}; | ||
(@TAIL, $N:ident : $T:ty = $e:expr) => { | ||
impl $crate::lazy_static::__Deref for $N { | ||
type Target = $T; | ||
fn deref(&self) -> &$T { | ||
#[inline(always)] | ||
fn __static_ref_initialize() -> $T { $e } | ||
|
||
#[inline(always)] | ||
fn __stability() -> &'static $T { | ||
__lazy_static_create!(LAZY, $T); | ||
LAZY.get(__static_ref_initialize) | ||
} | ||
__stability() | ||
} | ||
} | ||
impl $crate::lazy_static::LazyStatic for $N { | ||
fn initialize(lazy: &Self) { | ||
let _ = &**lazy; | ||
} | ||
} | ||
}; | ||
// `vis` is wrapped in `()` to prevent parsing ambiguity | ||
(@MAKE TY, $(#[$attr:meta])*, ($($vis:tt)*), $N:ident) => { | ||
#[allow(missing_copy_implementations)] | ||
#[allow(non_camel_case_types)] | ||
#[allow(dead_code)] | ||
$(#[$attr])* | ||
$($vis)* struct $N {__private_field: ()} | ||
#[doc(hidden)] | ||
$($vis)* static $N: $N = $N {__private_field: ()}; | ||
}; | ||
() => () | ||
} | ||
|
||
#[macro_export(local_inner_macros)] | ||
/// lazy_static (suppress docs_missing warning) | ||
macro_rules! lazy_static { | ||
($(#[$attr:meta])* static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => { | ||
// use `()` to explicitly forward the information about private items | ||
__lazy_static_internal!($(#[$attr])* () static ref $N : $T = $e; $($t)*); | ||
}; | ||
($(#[$attr:meta])* pub static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => { | ||
__lazy_static_internal!($(#[$attr])* (pub) static ref $N : $T = $e; $($t)*); | ||
}; | ||
($(#[$attr:meta])* pub ($($vis:tt)+) static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => { | ||
__lazy_static_internal!($(#[$attr])* (pub ($($vis)+)) static ref $N : $T = $e; $($t)*); | ||
}; | ||
() => () | ||
} | ||
|
||
/// Support trait for enabling a few common operation on lazy static values. | ||
/// | ||
/// This is implemented by each defined lazy static, and | ||
/// used by the free functions in this crate. | ||
pub(crate) trait LazyStatic { | ||
#[doc(hidden)] | ||
fn initialize(lazy: &Self); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
The MIT License (MIT) | ||
|
||
Copyright (c) 2014 Mathijs van de Nes | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
//! Synchronization primitives based on spinning | ||
pub(crate) use mutex::*; | ||
pub use once::Once; | ||
|
||
mod mutex; | ||
mod once; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
use core::cell::UnsafeCell; | ||
use core::default::Default; | ||
use core::fmt; | ||
use core::marker::Sync; | ||
use core::ops::{Deref, DerefMut, Drop}; | ||
use core::option::Option::{self, None, Some}; | ||
use core::sync::atomic::{spin_loop_hint as cpu_relax, AtomicBool, Ordering}; | ||
|
||
/// This type provides MUTual EXclusion based on spinning. | ||
pub(crate) struct Mutex<T: ?Sized> { | ||
lock: AtomicBool, | ||
data: UnsafeCell<T>, | ||
} | ||
|
||
/// A guard to which the protected data can be accessed | ||
/// | ||
/// When the guard falls out of scope it will release the lock. | ||
#[derive(Debug)] | ||
pub(crate) struct MutexGuard<'a, T: ?Sized> { | ||
lock: &'a AtomicBool, | ||
data: &'a mut T, | ||
} | ||
|
||
// Same unsafe impls as `std::sync::Mutex` | ||
unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {} | ||
unsafe impl<T: ?Sized + Send> Send for Mutex<T> {} | ||
|
||
impl<T> Mutex<T> { | ||
/// Creates a new spinlock wrapping the supplied data. | ||
pub(crate) const fn new(user_data: T) -> Mutex<T> { | ||
Mutex { | ||
lock: AtomicBool::new(false), | ||
data: UnsafeCell::new(user_data), | ||
} | ||
} | ||
} | ||
|
||
impl<T: ?Sized> Mutex<T> { | ||
fn obtain_lock(&self) { | ||
while self.lock.compare_and_swap(false, true, Ordering::Acquire) != false { | ||
// Wait until the lock looks unlocked before retrying | ||
while self.lock.load(Ordering::Relaxed) { | ||
cpu_relax(); | ||
} | ||
} | ||
} | ||
|
||
/// Locks the spinlock and returns a guard. | ||
/// | ||
/// The returned value may be dereferenced for data access | ||
/// and the lock will be dropped when the guard falls out of scope. | ||
pub(crate) fn lock(&self) -> MutexGuard<'_, T> { | ||
self.obtain_lock(); | ||
MutexGuard { | ||
lock: &self.lock, | ||
data: unsafe { &mut *self.data.get() }, | ||
} | ||
} | ||
|
||
/// Tries to lock the mutex. If it is already locked, it will return None. Otherwise it returns | ||
/// a guard within Some. | ||
pub(crate) fn try_lock(&self) -> Option<MutexGuard<'_, T>> { | ||
if self.lock.compare_and_swap(false, true, Ordering::Acquire) == false { | ||
Some(MutexGuard { | ||
lock: &self.lock, | ||
data: unsafe { &mut *self.data.get() }, | ||
}) | ||
} else { | ||
None | ||
} | ||
} | ||
} | ||
|
||
impl<T: ?Sized + fmt::Debug> fmt::Debug for Mutex<T> { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
match self.try_lock() { | ||
Some(guard) => write!(f, "Mutex {{ data: ") | ||
.and_then(|()| (&*guard).fmt(f)) | ||
.and_then(|()| write!(f, "}}")), | ||
None => write!(f, "Mutex {{ <locked> }}"), | ||
} | ||
} | ||
} | ||
|
||
impl<T: ?Sized + Default> Default for Mutex<T> { | ||
fn default() -> Mutex<T> { | ||
Mutex::new(Default::default()) | ||
} | ||
} | ||
|
||
impl<'a, T: ?Sized> Deref for MutexGuard<'a, T> { | ||
type Target = T; | ||
fn deref<'b>(&'b self) -> &'b T { | ||
&*self.data | ||
} | ||
} | ||
|
||
impl<'a, T: ?Sized> DerefMut for MutexGuard<'a, T> { | ||
fn deref_mut<'b>(&'b mut self) -> &'b mut T { | ||
&mut *self.data | ||
} | ||
} | ||
|
||
impl<'a, T: ?Sized> Drop for MutexGuard<'a, T> { | ||
/// The dropping of the MutexGuard will release the lock it was created from. | ||
fn drop(&mut self) { | ||
self.lock.store(false, Ordering::Release); | ||
} | ||
} |
Oops, something went wrong.