Kim Jørgensen
64 posts
I was wondering if it is possible to implement a lightweight version of GetThreadID that works on both Linux and Mac.

The following implementation is based on the disassembly of pthread_self and works on my machine™.

 1 2 3 4 5 6 inline u32 GetThreadID(void) { u32 ThreadID; asm ("mov %%fs:0x10,%0" : "=r" (ThreadID)); return ThreadID; } 

Does anybody know how portable this code is, will it work on Mac OS X?

Oh, and please point out if I did something stupid. I obviously have no clue what I am doing.

/Kim
Mārtiņš Možeiko
2453 posts / 2 projects
Edited by Mārtiņš Možeiko on
 1 2 3 4 5 pthread_t __pthread_self (void) { return (pthread_t) THREAD_SELF; } 

For 32-bit Intel it is https://sourceware.org/git/?p=gli...deps/i386/nptl/tls.h;hb=HEAD#l251
 1 2 3 4 5 # define THREAD_SELF \ ({ struct pthread *__self; \ asm ("movl %%gs:%c1,%0" : "=r" (__self) \ : "i" (offsetof (struct pthread, header.self))); \ __self;}) 

For 64-bit Intel it is https://sourceware.org/git/?p=gli...ps/x86_64/nptl/tls.h;hb=HEAD#l183
 1 2 3 4 5 # define THREAD_SELF \ ({ struct pthread *__self; \ asm ("mov %%fs:%c1,%0" : "=r" (__self) \ : "i" (offsetof (struct pthread, header.self))); \ __self;}) 

  1 2 3 4 5 6 7 8 9 10 11 struct pthread { union { #if !TLS_DTV_AT_TP /* This overlaps the TCB as used for TLS without threads (see tls.h). */ tcbhead_t header; #else struct { ... 

 1 2 3 4 5 6 7 8 typedef struct { void *tcb; /* Pointer to the TCB. Not necessarily the thread descriptor used by libpthread. */ dtv_t *dtv; void *self; /* Pointer to the thread descriptor. */ ... } tcbhead_t; 

 1 2 3 4 5 6 7 8 typedef struct { void *tcb; /* Pointer to the TCB. Not necessarily the thread descriptor used by libpthread. */ dtv_t *dtv; void *self; /* Pointer to the thread descriptor. */ ... } tcbhead_t; 
  1 2 3 4 5 6 7 8 9 10 11 12 inline u32 GetThreadID(void) { void *ThreadID; #if defined(__i386__) asm("movl %%gs:0x08,%0" : "=r"(ThreadID)); #elif defined(__x86_64__) asm("mov %%fs:0x10,%0" : "=r"(ThreadID)); #else #error Unsupported architecture #endif return (u32)ThreadID; }