views:

36

answers:

1

I have a thread datatype in the interpreter implementation for a programming language I am working on. For various reasons, it’s a fairly common operation, to need to get the current thread (which is, itself, a pointer: a struct thread*).

However, pthread_self(3) hands me a pthread_t, which is an opaque type; on some systems, it seems to be an unsigned long, but I hear I can’t depend on that being the case. I suspect a hash table is the proper implementation of this unique mapping (pthread_t ID to struct thread pointer); however, I have no idea how to hash the pthread_t reliably.

I would appreciate advice from anybody with more experience with pthread(3) or, really, any situation wherein you have to “hash” an opaque datatype.

+5  A: 

I think the best way to hold your struct thread* is thread-local storage. Something like:

static pthread_key_t struct_thread_key;
pthread_key_create(&struct_thread_key, NULL);

In the thread initalizer:

struct thread *my_thread = malloc(sizeof(*my_thread));
// ...
pthread_setspecific(struct_thread_key, my_thread);

To access the current thread later:

struct thread *my_thread = (struct thread *) pthread_getspecific(struct_thread_key);
Matthew Flaschen
why didn't I think of that...
Spudd86
I’m not familiar with local storage, but that might be problematic: the `thread` has to be accessible from, well, other threads of execution: it’s a first-class datatype, that can be passed around freely. It’s only getting the `thread` for the *currently executing* thread of execution, as one of those first-class references, that is problematic…
elliottcable
@elliott, after you call `getspecific`, you can pass `my_thread` around. You still may need to do synchronization, of course.
Matthew Flaschen
@elliottcable: That should be fine, since in this example it is the *pointer* to the `struct thread` that is thread-local; the `struct thread` itself is allocated with `malloc()`, so it is global.
caf
Ah, I commented before seeing your edits; you’re talking about storing *a pointer* to shared memory, in the thread-specific memory for every thread, which stores a reference to that thread’s thread-struct datatype. Perfect! I never considered a solution which didn’t employ `pthread_self(3)` somehow, that’s genius. Thanks! :D
elliottcable
Hm. `pthread_setspecific(3)` takes a `const void*` as its second argument; are you sure I want to be passing `struct thread*` into it? Should I be be passing ` the manpage is a bit unclear on the topic…
elliottcable
Matthew Flaschen