title: Implementing fast "GetCurrentThreadId" in Linux
body: <p>Windows NT has a nice function named <code>GetCurrentThreadId</code> that does what its name implies.  Its implementation is very fast because it merely reads a variable from thread-local storage that is written there during thread creation by the NT kernel.  I'd like to implement that in Linux, but I've run into a snag.</p>
  
  <p>My initial implementation was this:</p>
  
  <pre><code>typedef pid_t ThreadID;
  
  ThreadID GetCurrentThreadId(void)
  {
      static __thread ThreadID t_cachedID = (ThreadID) -1;
  
      if (__builtin_expect(t_cachedID == (ThreadID) -1, 0))
      {
          t_cachedID = (ThreadID) syscall(__NR_gettid);
      }
  
      return t_cachedID;
  }
  </code></pre>
  
  <p>The problem is <code>fork</code>.  In programs that use <code>fork</code>, <code>t_cachedID</code> becomes stale - the new child process's main thread has a copy of the thread-local storage of the thread that called <code>fork</code>, and that <code>t_cachedID</code> is no longer correct.</p>
  
  <p>The solution is supposed to be <code>pthread_atfork</code>, so as to change the <code>t_cachedID</code> value in the new child process to -1, but as is the norm for the Pthreads API, it's poorly-designed.  If you are a DLL that gets unloaded using <code>dlclose</code>, <code>pthread_atfork</code> doesn't know this, and will still try to call your function upon a <code>fork</code>, and kaboom.  Poor design decision #1.  There is no API to remove your callback function, either.  Poor design decision #2.</p>
  
  <p>There is an vaguely-documented glibc function named <code>__register_atfork</code> that seems designed to handle this problem, but it takes a DLL handle instead of providing a way to remove your <code>*_atfork</code> handler.  Poor design decision #1 by glibc when trying to work around POSIX's poor design decisions.</p>
  
  <p>How do I get my own DLL handle?  In Linux, it seems like <code>dlopen</code> returns a different <code>void *</code> handle for each time someone calls <code>dlopen</code> on a DLL/.so file, rather than merely maintaining a reference count...?  It's not like Windows where a DLL handle equals the base address of the section mapping.  Unless there's some easy way to get your own DLL handle in Linux, this makes poor design decision #2.</p>
  
  <p>Is there a better, proper way to do this?</p>