Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread local data in C

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.

My question is if I allocate memory to static thread local storage will it be deleted upon thread exit ?

Here is my code:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <pthread.h>


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", &val, val);
    printf ("string(%p):%s\n", &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<num_threads;i++) {
        pthread_create (&tid[i], NULL, &test, NULL);
    }

    for (i=0;i<num_threads;i++) {
        pthread_join (tid[i], NULL);
    }

    return 0;
}

output:

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

valgrind:

==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
like image 643
user2962313 Avatar asked Nov 06 '13 21:11

user2962313


People also ask

What is a ThreadLocal in C?

Thread-local storage (TLS) is a mechanism by which variables are allocated such that there is one instance of the variable per extant thread. The run-time model GCC uses to implement this originates in the IA-64 processor-specific ABI, but has since been migrated to other processors as well.

What is ThreadLocal data?

Thread Local Storage (TLS) is the mechanism by which each thread in a given multithreaded process allocates storage for thread-specific data. In standard multithreaded programs, data is shared among all threads of a given process, whereas thread local storage is the mechanism for allocating per-thread data.

What is ThreadLocal state?

Thread Local Storage (TLS) is the method by which each thread in a given multithreaded process can allocate locations in which to store thread-specific data. Dynamically bound (run-time) thread-specific data is supported by way of the TLS API (TlsAlloc).

What is difference between thread-local storage and static data?

In some ways, TLS is similar to static data. The only difference is that TLS data are unique to each thread. Most thread libraries-including Windows and Pthreads-provide some form of support for thread-local storage; Java provides support as well.


2 Answers

It will not be automatically deleted upon thread exit. You've declared a pointer in thread local storage. the runtime framework doesn't know how you intend to use that object, so it cannot assume that memory was dynamically allocated.

You are required to free that memory on your own.

like image 111
Chad Avatar answered Oct 23 '22 06:10

Chad


Yes, you should free before the pthread_exit. pthread_exit does not free automatically.

free(string);

should do.

like image 21
Arjen Avatar answered Oct 23 '22 06:10

Arjen