Skip to content

Add direct access to the thread id #650

@jsimmons

Description

@jsimmons

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

rust-lang/rust#143069

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    ACP-acceptedAPI Change Proposal is accepted (seconded with no objections)T-libs-apiapi-change-proposalA proposal to add or alter unstable APIs in the standard libraries

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions