Skip to content

Commit 7f92bce

Browse files
authored
tokio: use const initialized thread locals where possible (#4677)
1 parent 7ed2737 commit 7f92bce

File tree

8 files changed

+69
-4
lines changed

8 files changed

+69
-4
lines changed

tokio/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ time = []
100100
# a few releases.
101101
stats = []
102102

103+
[build-dependencies]
104+
autocfg = "1.1"
105+
103106
[dependencies]
104107
tokio-macros = { version = "1.7.0", path = "../tokio-macros", optional = true }
105108

tokio/build.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use autocfg::AutoCfg;
2+
3+
fn main() {
4+
match AutoCfg::new() {
5+
Ok(ac) => {
6+
// Const-initialized thread locals were stabilized in 1.59
7+
if ac.probe_rustc_version(1, 59) {
8+
autocfg::emit("tokio_const_thread_local")
9+
}
10+
}
11+
12+
Err(e) => {
13+
// If we couldn't detect the compiler version and features, just
14+
// print a warning. This isn't a fatal error: we can still build
15+
// Tokio, we just can't enable cfgs automatically.
16+
println!(
17+
"cargo:warning=tokio: failed to detect compiler features: {}",
18+
e
19+
);
20+
}
21+
}
22+
}

tokio/src/coop.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
use std::cell::Cell;
3333

3434
thread_local! {
35-
static CURRENT: Cell<Budget> = Cell::new(Budget::unconstrained());
35+
static CURRENT: Cell<Budget> = const { Cell::new(Budget::unconstrained()) };
3636
}
3737

3838
/// Opaque type tracking the amount of "work" a task may still do before

tokio/src/macros/scoped_tls.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ macro_rules! scoped_thread_local {
1010
$vis static $name: $crate::macros::scoped_tls::ScopedKey<$ty>
1111
= $crate::macros::scoped_tls::ScopedKey {
1212
inner: {
13-
thread_local!(static FOO: ::std::cell::Cell<*const ()> = {
13+
thread_local!(static FOO: ::std::cell::Cell<*const ()> = const {
1414
std::cell::Cell::new(::std::ptr::null())
1515
});
1616
&FOO

tokio/src/macros/thread_local.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,28 @@
11
#[cfg(all(loom, test))]
22
macro_rules! thread_local {
3+
($(#[$attrs:meta])* $vis:vis static $name:ident: $ty:ty = const { $expr:expr } $(;)?) => {
4+
loom::thread_local! {
5+
$(#[$attrs])*
6+
$vis static $name: $ty = $expr;
7+
}
8+
};
9+
310
($($tts:tt)+) => { loom::thread_local!{ $($tts)+ } }
411
}
12+
13+
#[cfg(all(tokio_const_thread_local, not(all(loom, test))))]
14+
macro_rules! thread_local {
15+
($($tts:tt)+) => { ::std::thread_local!{ $($tts)+ } }
16+
}
17+
18+
#[cfg(all(not(tokio_const_thread_local), not(all(loom, test))))]
19+
macro_rules! thread_local {
20+
($(#[$attrs:meta])* $vis:vis static $name:ident: $ty:ty = const { $expr:expr } $(;)?) => {
21+
::std::thread_local! {
22+
$(#[$attrs])*
23+
$vis static $name: $ty = $expr;
24+
}
25+
};
26+
27+
($($tts:tt)+) => { ::std::thread_local!{ $($tts)+ } }
28+
}

tokio/src/runtime/context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::runtime::{Handle, TryCurrentError};
44
use std::cell::RefCell;
55

66
thread_local! {
7-
static CONTEXT: RefCell<Option<Handle>> = RefCell::new(None)
7+
static CONTEXT: RefCell<Option<Handle>> = const { RefCell::new(None) }
88
}
99

1010
pub(crate) fn try_current() -> Result<Handle, crate::runtime::TryCurrentError> {

tokio/src/runtime/enter.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ impl EnterContext {
1717
}
1818
}
1919

20-
thread_local!(static ENTERED: Cell<EnterContext> = Cell::new(EnterContext::NotEntered));
20+
thread_local!(static ENTERED: Cell<EnterContext> = const { Cell::new(EnterContext::NotEntered) });
2121

2222
/// Represents an executor context.
2323
pub(crate) struct Enter {

tokio/src/task/task_local.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,22 @@ macro_rules! task_local {
4848
}
4949

5050
#[doc(hidden)]
51+
#[cfg(tokio_const_thread_local)]
52+
#[macro_export]
53+
macro_rules! __task_local_inner {
54+
($(#[$attr:meta])* $vis:vis $name:ident, $t:ty) => {
55+
$vis static $name: $crate::task::LocalKey<$t> = {
56+
std::thread_local! {
57+
static __KEY: std::cell::RefCell<Option<$t>> = const { std::cell::RefCell::new(None) };
58+
}
59+
60+
$crate::task::LocalKey { inner: __KEY }
61+
};
62+
};
63+
}
64+
65+
#[doc(hidden)]
66+
#[cfg(not(tokio_const_thread_local))]
5167
#[macro_export]
5268
macro_rules! __task_local_inner {
5369
($(#[$attr:meta])* $vis:vis $name:ident, $t:ty) => {

0 commit comments

Comments
 (0)