-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
rt: use internal ThreadId implementation #5184
Conversation
The version provided by `std` has limitations, including no way to try to get a thread ID without panicking.
cfg_has_atomic_u64! { | ||
pub(crate) fn new() -> ThreadId { | ||
use std::sync::atomic::{AtomicU64, Ordering::Relaxed}; | ||
|
||
static COUNTER: AtomicU64 = AtomicU64::new(0); | ||
|
||
let mut last = COUNTER.load(Relaxed); | ||
loop { | ||
let id = match last.checked_add(1) { | ||
Some(id) => id, | ||
None => exhausted(), | ||
}; | ||
|
||
match COUNTER.compare_exchange_weak(last, id, Relaxed, Relaxed) { | ||
Ok(_) => return ThreadId(NonZeroU64::new(id).unwrap()), | ||
Err(id) => last = id, | ||
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems to me that doing the same as in list.rs
would be sufficient here.
tokio/tokio/src/runtime/task/list.rs
Lines 17 to 54 in fbae620
// The id from the module below is used to verify whether a given task is stored | |
// in this OwnedTasks, or some other task. The counter starts at one so we can | |
// use zero for tasks not owned by any list. | |
// | |
// The safety checks in this file can technically be violated if the counter is | |
// overflown, but the checks are not supposed to ever fail unless there is a | |
// bug in Tokio, so we accept that certain bugs would not be caught if the two | |
// mixed up runtimes happen to have the same id. | |
cfg_has_atomic_u64! { | |
use std::sync::atomic::{AtomicU64, Ordering}; | |
static NEXT_OWNED_TASKS_ID: AtomicU64 = AtomicU64::new(1); | |
fn get_next_id() -> u64 { | |
loop { | |
let id = NEXT_OWNED_TASKS_ID.fetch_add(1, Ordering::Relaxed); | |
if id != 0 { | |
return id; | |
} | |
} | |
} | |
} | |
cfg_not_has_atomic_u64! { | |
use std::sync::atomic::{AtomicU32, Ordering}; | |
static NEXT_OWNED_TASKS_ID: AtomicU32 = AtomicU32::new(1); | |
fn get_next_id() -> u64 { | |
loop { | |
let id = NEXT_OWNED_TASKS_ID.fetch_add(1, Ordering::Relaxed); | |
if id != 0 { | |
return u64::from(id); | |
} | |
} | |
} | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do use the thread ID for correctness on top of the debug checks. It seems riskier, in that case, to fall back to u32.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC std
's thread IDs use a mutex on 32-bit targets, but I'd have to double check to make sure...
edit: oh, i see that that's not actually what this conversation was about, my bad.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where do we use it for correctness?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implemented by #5329 |
The version provided by
std
has limitations, including no way to try to get a thread ID without panicking.