Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core: vendor lazy_static and spin for no_std support #424

Merged
merged 9 commits into from
Nov 16, 2019
8 changes: 0 additions & 8 deletions tracing-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,3 @@ std = []
[badges]
azure-devops = { project = "tracing/tracing", pipeline = "tokio-rs.tracing", build = "1" }
maintenance = { status = "actively-developed" }

[dependencies]
lazy_static = "1"

[target.'cfg(not(feature = "std"))'.dependencies]
spin = "0.5"
lazy_static = { version = "1", features = ["spin_no_std"] }

1 change: 1 addition & 0 deletions tracing-core/src/callsite.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Callsites represent the source locations from which spans or events
//! originate.
use crate::lazy_static;
use crate::stdlib::{
fmt,
hash::{Hash, Hasher},
Expand Down
26 changes: 26 additions & 0 deletions tracing-core/src/lazy_static/LICENSE
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.
30 changes: 30 additions & 0 deletions tracing-core/src/lazy_static/core_lazy.rs
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::spin::Once;

pub struct Lazy<T: Sync>(Once<T>);

impl<T: Sync> Lazy<T> {
pub const INIT: Self = Lazy(Once::INIT);

#[inline(always)]
pub 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::Lazy<$T> = $crate::lazy::Lazy::INIT;
};
}
58 changes: 58 additions & 0 deletions tracing-core/src/lazy_static/inline_lazy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// 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 std::cell::Cell;
use std::hint::unreachable_unchecked;
use std::prelude::v1::*;
use std::sync::Once;
#[allow(deprecated)]
pub use std::sync::ONCE_INIT;

// FIXME: Replace Option<T> with MaybeUninit<T> (stable since 1.36.0)
#[allow(missing_debug_implementations)]
pub struct Lazy<T: Sync>(Cell<Option<T>>, Once);

impl<T: Sync> Lazy<T> {
#[allow(deprecated)]
pub const INIT: Self = Lazy(Cell::new(None), ONCE_INIT);

#[inline(always)]
pub fn get<F>(&'static self, f: F) -> &T
where
F: FnOnce() -> T,
{
self.1.call_once(|| {
self.0.set(Some(f()));
});

// `self.0` is guaranteed to be `Some` by this point
// The `Once` will catch and propagate panics
unsafe {
match *self.0.as_ptr() {
Some(ref x) => x,
None => {
debug_assert!(
false,
"attempted to derefence an uninitialized lazy static. This is a bug"
);

unreachable_unchecked()
}
}
}
}
}

unsafe impl<T: Sync> Sync for Lazy<T> {}

#[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;
};
}
104 changes: 104 additions & 0 deletions tracing-core/src/lazy_static/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// 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.
*/

#[cfg(feature = "std")]
#[path = "inline_lazy.rs"]
#[doc(hidden)]
pub mod lazy;

#[cfg(not(feature = "std"))]
#[path = "core_lazy.rs"]
#[doc(hidden)]
pub mod lazy;

#[doc(hidden)]
pub 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 trait LazyStatic {
#[doc(hidden)]
fn initialize(lazy: &Self);
}

/// Takes a shared reference to a lazy static and initializes
/// it if it has not been already.
///
/// This can be used to control the initialization point of a lazy static.
pub fn initialize<T: LazyStatic>(lazy: &T) {
LazyStatic::initialize(lazy);
}
11 changes: 8 additions & 3 deletions tracing-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,6 @@
#[cfg(not(feature = "std"))]
extern crate alloc;

#[macro_use]
extern crate lazy_static;

/// Statically constructs an [`Identifier`] for the provided [`Callsite`].
///
/// This may be used in contexts, such as static initializers, where the
Expand Down Expand Up @@ -219,6 +216,14 @@ pub mod span;
pub(crate) mod stdlib;
pub mod subscriber;

// Vendored version of spin 0.5.2 (0387621)
// `mutex` and `once` modules only
thombles marked this conversation as resolved.
Show resolved Hide resolved
#[cfg(not(feature = "std"))]
pub mod spin;
thombles marked this conversation as resolved.
Show resolved Hide resolved

// Vendored version of lazy_static 1.4.0 (4216696)
thombles marked this conversation as resolved.
Show resolved Hide resolved
pub mod lazy_static;
thombles marked this conversation as resolved.
Show resolved Hide resolved

#[doc(inline)]
pub use self::{
callsite::Callsite,
Expand Down
21 changes: 21 additions & 0 deletions tracing-core/src/spin/LICENSE
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.
11 changes: 11 additions & 0 deletions tracing-core/src/spin/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//! Synchronization primitives based on spinning

#[cfg(test)]
#[macro_use]
extern crate std;

pub use mutex::*;
pub use once::*;

mod mutex;
mod once;
Loading