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
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.
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.
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).
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.
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.
Yes, you should free before the pthread_exit. pthread_exit does not free automatically.
free(string);
should do.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With