tokio: use const initialized thread locals where possible (#4677)

This commit is contained in:
Alphyr 2022-06-29 11:32:14 +02:00 committed by GitHub
parent 7ed2737de2
commit 7f92bce39f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 69 additions and 4 deletions

View File

@ -100,6 +100,9 @@ time = []
# a few releases.
stats = []
[build-dependencies]
autocfg = "1.1"
[dependencies]
tokio-macros = { version = "1.7.0", path = "../tokio-macros", optional = true }

22
tokio/build.rs Normal file
View File

@ -0,0 +1,22 @@
use autocfg::AutoCfg;
fn main() {
match AutoCfg::new() {
Ok(ac) => {
// Const-initialized thread locals were stabilized in 1.59
if ac.probe_rustc_version(1, 59) {
autocfg::emit("tokio_const_thread_local")
}
}
Err(e) => {
// If we couldn't detect the compiler version and features, just
// print a warning. This isn't a fatal error: we can still build
// Tokio, we just can't enable cfgs automatically.
println!(
"cargo:warning=tokio: failed to detect compiler features: {}",
e
);
}
}
}

View File

@ -32,7 +32,7 @@
use std::cell::Cell;
thread_local! {
static CURRENT: Cell<Budget> = Cell::new(Budget::unconstrained());
static CURRENT: Cell<Budget> = const { Cell::new(Budget::unconstrained()) };
}
/// Opaque type tracking the amount of "work" a task may still do before

View File

@ -10,7 +10,7 @@ macro_rules! scoped_thread_local {
$vis static $name: $crate::macros::scoped_tls::ScopedKey<$ty>
= $crate::macros::scoped_tls::ScopedKey {
inner: {
thread_local!(static FOO: ::std::cell::Cell<*const ()> = {
thread_local!(static FOO: ::std::cell::Cell<*const ()> = const {
std::cell::Cell::new(::std::ptr::null())
});
&FOO

View File

@ -1,4 +1,28 @@
#[cfg(all(loom, test))]
macro_rules! thread_local {
($(#[$attrs:meta])* $vis:vis static $name:ident: $ty:ty = const { $expr:expr } $(;)?) => {
loom::thread_local! {
$(#[$attrs])*
$vis static $name: $ty = $expr;
}
};
($($tts:tt)+) => { loom::thread_local!{ $($tts)+ } }
}
#[cfg(all(tokio_const_thread_local, not(all(loom, test))))]
macro_rules! thread_local {
($($tts:tt)+) => { ::std::thread_local!{ $($tts)+ } }
}
#[cfg(all(not(tokio_const_thread_local), not(all(loom, test))))]
macro_rules! thread_local {
($(#[$attrs:meta])* $vis:vis static $name:ident: $ty:ty = const { $expr:expr } $(;)?) => {
::std::thread_local! {
$(#[$attrs])*
$vis static $name: $ty = $expr;
}
};
($($tts:tt)+) => { ::std::thread_local!{ $($tts)+ } }
}

View File

@ -4,7 +4,7 @@ use crate::runtime::{Handle, TryCurrentError};
use std::cell::RefCell;
thread_local! {
static CONTEXT: RefCell<Option<Handle>> = RefCell::new(None)
static CONTEXT: RefCell<Option<Handle>> = const { RefCell::new(None) }
}
pub(crate) fn try_current() -> Result<Handle, crate::runtime::TryCurrentError> {

View File

@ -17,7 +17,7 @@ impl EnterContext {
}
}
thread_local!(static ENTERED: Cell<EnterContext> = Cell::new(EnterContext::NotEntered));
thread_local!(static ENTERED: Cell<EnterContext> = const { Cell::new(EnterContext::NotEntered) });
/// Represents an executor context.
pub(crate) struct Enter {

View File

@ -48,6 +48,22 @@ macro_rules! task_local {
}
#[doc(hidden)]
#[cfg(tokio_const_thread_local)]
#[macro_export]
macro_rules! __task_local_inner {
($(#[$attr:meta])* $vis:vis $name:ident, $t:ty) => {
$vis static $name: $crate::task::LocalKey<$t> = {
std::thread_local! {
static __KEY: std::cell::RefCell<Option<$t>> = const { std::cell::RefCell::new(None) };
}
$crate::task::LocalKey { inner: __KEY }
};
};
}
#[doc(hidden)]
#[cfg(not(tokio_const_thread_local))]
#[macro_export]
macro_rules! __task_local_inner {
($(#[$attr:meta])* $vis:vis $name:ident, $t:ty) => {