Skip to content

Commit 7a3ddfb

Browse files
core: add portable-atomic support (#3199)
## Motivation I want to use `bevy_reflect` on `no_std` devices. This platform has alloc, but not atomics, so `alloc::sync` is missing. `bevy_relflect` has a hard depency on `tracing`, and I'd like to use tracing on this platform also. Want to use tracing-core on `no_std` devices like rp2040 without hardware atomics ## Solution - Added `portable-atomic-util` as an optional dependency gated behind a new feature, `portable-atomic` to `tracing-core` - When `portable-atomic` is enabled, switched uses of `Arc` and `Weak` away from `alloc::sync` to `portable_atomic_util`. - Added workaround for a lack of support for [unsized coercion](rust-lang/rust#18598) in custom types. I've included a comment linking to this issue explaining the missing functionality. Fixes #3173
1 parent d6505ca commit 7a3ddfb

File tree

3 files changed

+29
-5
lines changed

3 files changed

+29
-5
lines changed

tracing-core/Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,16 @@ rust-version = "1.63.0"
2626

2727
[features]
2828
default = ["std"]
29-
alloc = []
30-
std = ["once_cell", "alloc"]
29+
alloc = ["portable-atomic-util?/alloc"]
30+
std = ["once_cell", "alloc", "portable-atomic-util?/std"]
31+
portable-atomic = ["dep:portable-atomic-util", "once_cell?/portable-atomic"]
3132

3233
[badges]
3334
maintenance = { status = "actively-developed" }
3435

3536
[dependencies]
3637
once_cell = { version = "1.13.0", optional = true }
38+
portable-atomic-util = { version = "0.2.4", default-features = false, optional = true }
3739

3840
[package.metadata.docs.rs]
3941
all-features = true

tracing-core/src/collect.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ use crate::{span, Dispatch, Event, LevelFilter, Metadata};
44
use core::any::{Any, TypeId};
55
use core::ptr::NonNull;
66

7+
#[cfg(all(feature = "alloc", not(feature = "portable-atomic")))]
8+
use alloc::sync::Arc;
9+
10+
#[cfg(all(feature = "alloc", feature = "portable-atomic"))]
11+
use portable_atomic_util::Arc;
12+
713
/// Trait representing the functions required to collect trace data.
814
///
915
/// Crates that provide implementations of methods for collecting or recording
@@ -772,7 +778,7 @@ where
772778
}
773779

774780
#[cfg(feature = "alloc")]
775-
impl<C> Collect for alloc::sync::Arc<C>
781+
impl<C> Collect for Arc<C>
776782
where
777783
C: Collect + ?Sized,
778784
{

tracing-core/src/dispatch.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,12 @@ use std::{
152152
error,
153153
};
154154

155-
#[cfg(feature = "alloc")]
155+
#[cfg(all(feature = "alloc", not(feature = "portable-atomic")))]
156156
use alloc::sync::{Arc, Weak};
157157

158+
#[cfg(all(feature = "alloc", feature = "portable-atomic"))]
159+
use portable_atomic_util::{Arc, Weak};
160+
158161
#[cfg(feature = "alloc")]
159162
use core::ops::Deref;
160163

@@ -539,8 +542,21 @@ impl Dispatch {
539542
where
540543
C: Collect + Send + Sync + 'static,
541544
{
545+
#[cfg(not(feature = "portable-atomic"))]
546+
let arc = Arc::new(collector);
547+
548+
#[cfg(feature = "portable-atomic")]
549+
let arc = {
550+
use alloc::boxed::Box;
551+
552+
// Workaround for a lack of support for unsized coercion in non-first-party types.
553+
// See https://github.com/rust-lang/rust/issues/18598
554+
let boxed: Box<dyn Collect + Send + Sync> = Box::<C>::new(collector);
555+
Arc::from(boxed)
556+
};
557+
542558
let me = Dispatch {
543-
collector: Kind::Scoped(Arc::new(collector)),
559+
collector: Kind::Scoped(arc),
544560
};
545561
crate::callsite::register_dispatch(&me);
546562
me

0 commit comments

Comments
 (0)