-
Notifications
You must be signed in to change notification settings - Fork 23
Description
Proposal
Add direct access to the thread id.
Problem statement
Accessing the thread id requires first accessing the thread context, which is not free. The thread context itself is an Arc, and so grabbing the current thread context requires at least an atomic fetch-add, atomic fetch-sub and injection of the drop handler in the caller.
The assembly works out something like this:
push rbx
sub rsp, 16
call qword ptr [rip + std::thread::current::current]
mov qword ptr [rsp + 8], rax
mov rbx, qword ptr [rax + 16]
lock dec qword ptr [rax]
jne .DONE
lea rdi, [rsp + 8]
call qword ptr [rip + alloc::sync::Arc<T,A>::drop_slow]
.DONE:
mov rax, rbx
add rsp, 16
pop rbx
ret
Where std::thread::current
looks up the Thread
in TLS, and then Thread::id
looks up the id
field.
However if we access directly, it's a singular TLS load in the good case, and the same lookup via the Thread
in the worst case - but without the Arc maintenance.
Something like...
push rbx
mov rbx,0xffffffffffffffe0
mov rax,QWORD PTR fs:[rbx]
test rax,rax
je .SLOW
pop rbx
ret
.SLOW:
call QWORD PTR [rip+std::thread::ThreadId::new]
mov QWORD PTR fs:[rbx],rax
pop rbx
ret
Furthermore, the existing current_id
implementation (internally) promises to not invoke the global allocator, which is helpful in embedded / realtime contexts especially.
Motivating examples or use cases
On a work-queue push:
https://github.com/tikv/grpc-rs/blob/edb4d961cd71a3758f015577c577f6e3f735b6f4/src/cq.rs#L165-L172
Wrapping non-send types in a sendable wrapper:
https://github.com/mitsuhiko/fragile/blob/7631a72b0a4a47fb8251cc2ad641f3db8fd1b565/src/fragile.rs#L41-L46
Manually caching the thread id in TLS for performance:
https://github.com/SAP/transactional-storage-framework/blob/e84d92edf5999660fb8448831a610840def50e66/src/utils.rs#L25-L41
Non-allocating access to the thread id to the thread id:
https://github.com/robbert-vdh/nih-plug/blob/ecfd6322c776d9f0373d31758976c2353c162737/src/event_loop/linux.rs#L61-L65
Solution sketch
Alternatives
Leave it as-is.
Links and related work
The C++ std exposes a free function for accessing the thread id. https://en.cppreference.com/w/cpp/thread/get_id.html