Skip to content
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

Add a numeric ID to threads #29448

Closed
wants to merge 4 commits into from

Conversation

Projects
None yet
8 participants
@remram44
Copy link
Contributor

remram44 commented Oct 29, 2015

See #21507

Because we only get an ID once the thread has been spawned, and at that point the Inner struct is referenced from both the thread (which is gonna store it in the threadlocal thread_info) and the parent (which returns it), it was much easier to add it to Thread than to Inner. It is a single u32 so I'm not sure the memory usage is an issue, but it is a little awkward to have id in Thread and name in Inner?

Let me know.

@rust-highfive

This comment has been minimized.

Copy link
Collaborator

rust-highfive commented Oct 29, 2015

r? @brson

(rust_highfive has picked a reviewer for you, use r? to override)

///
/// This ID is unique across running threads, and a thread that has stopped
/// might see its ID reused.
pub fn id(&self) -> u32 {

This comment has been minimized.

@huonw

huonw Oct 29, 2015

Member

If this PR is accepted, this will need to be marked #[unstable] and have a tracking issue opened. (See catch_panic in this module for an example.)

@@ -78,6 +78,10 @@ impl Thread {
c::Sleep(super::dur2timeout(dur))
}
}

pub fn id(&self) -> u32 {
42 // TODO

This comment has been minimized.

@retep998

retep998 Oct 29, 2015

Member

On Windows this is done either via GetCurrentThreadId or GetThreadId.

@@ -71,7 +71,7 @@ impl Thread {
};

extern fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
unsafe { start_thread(main); }
unsafe { start_thread(main, pthread_self() as u32); }

This comment has been minimized.

@nagisa

nagisa Oct 29, 2015

Contributor

This is wrong.

POSIX.1 allows an implementation wide freedom in choosing the type used to represent a thread ID; for example, representation using either an arithmetic type or a structure is permitted.

This comment has been minimized.

@retep998

retep998 Oct 29, 2015

Member

So should we use a typedef around what a thread ID is?

This comment has been minimized.

@remram44

remram44 Oct 29, 2015

Author Contributor

On Linux pthread_t is unsigned long, thus u64 on amd64. There is no portable way to get a numeric ID from pthreads (pthread_getthreadid_np is not portable).

I'm starting to think that using the address of the Inner struct is way simpler and would totally work (it's what I used for #29447) if we want "some kind of ID" and don't care for the OS-provided ID.

This comment has been minimized.

@retep998

retep998 Oct 29, 2015

Member

On Windows what I want is some sort of OS provided ID. Either the thread HANDLE or the thread ID which is a DWORD. Anything else would be useless to me as I wouldn't be able to use it in OS functions to manipulate that thread like queuing APCs to it.

This comment has been minimized.

@retep998

retep998 Oct 29, 2015

Member

Nevermind, I'm fine with this just providing some sort of unique numerical ID that has no meaning other than to distinguish threads. I'll work on a PR to add OS specific APIs for getting the HANDLE of a thread.

// Next, set up our stack overflow handler which may get triggered if we run
// out of stack.
let _handler = stack_overflow::Handler::new();

// Finally, let's run some code.
Box::from_raw(main as *mut Box<FnBox()>)()
Box::from_raw(main as *mut Box<FnBox(u32)>)(id)

This comment has been minimized.

@nagisa

nagisa Oct 29, 2015

Contributor

I do not understand why’d you want to pass the thread id as an argument into the thread instead of e.g. providing a static method on Thread which calls pthread_self.

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Oct 29, 2015

I think that there's a few pieces that may want to be tweaked here:

  • The id likely wants to be inside the Arc of the thread and just stored as an AtomicUsize. Both the parent and the child would initialize it.
  • The constructor Thread::new should perhaps not use 0 as the default as this means thread::current on every non-rust-spawned thread will have an id of 0 I believe.

I'm also not sure that we want to use the exact same ID as the underlying OS. As @nagisa points out we can't rely on pthread_t being an integer, so there may not always be an ID to assign.

@retep998

This comment has been minimized.

Copy link
Member

retep998 commented Oct 29, 2015

The constructor Thread::new should perhaps not use 0 as the default as this means thread::current on every non-rust-spawned thread will have an id of 0 I believe.

Getting the ID of the current thread is trivial, especially on Windows, so there shouldn't be any reason for thread::current to not return the correct ID.

@bors

This comment has been minimized.

Copy link
Contributor

bors commented Nov 10, 2015

☔️ The latest upstream changes (presumably #29546) made this pull request unmergeable. Please resolve the merge conflicts.

@brson

This comment has been minimized.

Copy link
Contributor

brson commented Nov 11, 2015

Haven't looked at this in detail, but because the Rust thread type outlives the system thread, it's possible for comparison operations to produce incorrect results if the system reuses the thread id.

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Nov 12, 2015

The libs team discussed this in triage today, and in addition to @brson's comment we also had thinking along the lines of:

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Dec 2, 2015

Closing due to inactivity, but feel free to resubmit with the comments on this and #29447 addressed!

bors added a commit that referenced this pull request Oct 10, 2016

Auto merge of #36341 - sagebind:thread_id, r=alexcrichton
Add ThreadId for comparing threads

This adds the capability to store and compare threads with the current calling thread via a new struct, `std::thread::ThreadId`. Addresses the need outlined in issue #21507.

This avoids the need to add any special checks to the existing thread structs and does not rely on the system to provide an identifier for a thread, since it seems that this approach is unreliable and undesirable. Instead, this simply uses a lazily-created, thread-local `usize` whose value is copied from a global atomic counter. The code should be simple enough that it should be as much reliable as the `#[thread_local]` attribute it uses (however much that is).

`ThreadId`s can be compared directly for equality and have copy semantics.

Also see these other attempts:
- #29457
- #29448
- #29447

And this in the RFC repo: rust-lang/rfcs#1435
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.