title: Thread local data in C
body: <p>I have been experimenting with thread local storage lately. I have working code and every thing seems to be fine but when I run my program with valgrind it looks like there are some issues.</p>
  
  <p>My question is if I allocate memory to static thread local storage will it be deleted upon thread exit ?</p>
  
  <p>Here is my code:</p>
  
  <pre><code>#include &lt;stdlib.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  
  #include &lt;pthread.h&gt;
  
  
  void *test (void *arg) 
  {
      static __thread int val = 0;
      static __thread char *string = NULL;
  
      string = (char *) calloc (100, sizeof (char));
  
      strcpy (string, "hello");
  
      val++;
  
      printf ("val(%p):%d\n", &amp;val, val);
      printf ("string(%p):%s\n", &amp;string, string);
  
      pthread_exit (NULL);
  }
  
  
  int main (int argc, char *argv[])
  {
      int num_threads = 10, i;
      pthread_t tid[num_threads];
  
      for (i=0;i&lt;num_threads;i++) {
          pthread_create (&amp;tid[i], NULL, &amp;test, NULL);
      }
  
      for (i=0;i&lt;num_threads;i++) {
          pthread_join (tid[i], NULL);
      }
  
      return 0;
  }
  </code></pre>
  
  <p>output:</p>
  
  <pre><code>val(0x7122b8c):1
  string(0x7122b88):hello
  val(0x7b23b8c):1
  string(0x7b23b88):hello
  val(0x924ab8c):1
  string(0x924ab88):hello
  val(0x9c4bb8c):1
  string(0x9c4bb88):hello
  val(0xa64cb8c):1
  string(0xa64cb88):hello
  val(0xb04db8c):1
  string(0xb04db88):hello
  val(0xba4eb8c):1
  string(0xba4eb88):hello
  val(0xc44fb8c):1
  string(0xc44fb88):hello
  val(0xce50b8c):1
  string(0xce50b88):hello
  val(0xd851b8c):1
  string(0xd851b88):hello
  </code></pre>
  
  <p>valgrind:</p>
  
  <pre><code>==9366== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 41 from 1)
  ==9366== malloc/free: in use at exit: 1,916 bytes in 15 blocks.
  ==9366== malloc/free: 70 allocs, 55 frees, 11,218 bytes allocated.
  ==9366== For counts of detected errors, rerun with: -v
  ==9366== searching for pointers to 15 not-freed blocks.
  ==9366== checked 335,336 bytes.
  ==9366== 
  ==9366== 1,000 bytes in 10 blocks are definitely lost in loss record 6 of 6
  ==9366==    at 0x43BB6FF: calloc (vg_replace_malloc.c:279)
  ==9366==    by 0x80485CD: test (pthread_test.c:14)
  ==9366==    by 0x51C73A: start_thread (in /lib/libpthread-2.5.so)
  ==9366==    by 0x4A0CFD: clone (in /lib/libc-2.5.so)
  ==9366== 
  ==9366== LEAK SUMMARY:
  ==9366==    definitely lost: 1,000 bytes in 10 blocks.
  ==9366==      possibly lost: 0 bytes in 0 blocks.
  ==9366==    still reachable: 916 bytes in 5 blocks.
  ==9366==         suppressed: 0 bytes in 0 blocks.
  ==9366== Reachable blocks (those to which a pointer was found) are not shown.
  ==9366== To see them, rerun with: --show-reachable=yes
  </code></pre>