Skip to content

Commit 9c693b8

Browse files
committed
Add TLS (thread-local storage) tests
Add tls/ folder. __thread.c highlights the use of implicit TLS, i.e. via the `__thread` storage class keyword. tsd.c uses explicit TLS, i.e. via `pthread_setspecific()` / `pthread_getspecific` function calls.
1 parent 41aca03 commit 9c693b8

File tree

4 files changed

+149
-0
lines changed

4 files changed

+149
-0
lines changed

tls/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/__thread
2+
/__thread-static
3+
/tsd
4+
/tsd-static

tls/Makefile

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
CFLAGS = -Wall
2+
LDLIBS = -lpthread
3+
4+
.PHONY: all clean
5+
6+
all: __thread __thread-static tsd tsd-static
7+
8+
__thread-static: __thread.o
9+
$(CC) $(LDLFAGS) -static -o $@ $^ $(LDLIBS)
10+
11+
__thread: __thread.o
12+
13+
__thread.o: __thread.c
14+
15+
tsd-static: tsd.o
16+
$(CC) $(LDLFAGS) -static -o $@ $^ $(LDLIBS)
17+
18+
tsd: tsd.o
19+
20+
tsd.o: tsd.c
21+
22+
clean:
23+
-rm -f __thread.o __thread __thread-static
24+
-rm -f tsd.o tsd tsd-static
25+
-rm -f *~

tls/__thread.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <pthread.h>
4+
#include <unistd.h>
5+
#include <errno.h>
6+
#include <sys/types.h>
7+
8+
static __thread size_t me;
9+
static __thread size_t you;
10+
static __thread size_t them = 543;
11+
12+
static void *tf(void *arg)
13+
{
14+
unsigned long id = (unsigned long) arg;
15+
static __thread size_t us = 13;
16+
17+
me = 200 + id;
18+
us += id*id;
19+
printf("me in thread (%p): %zu\n", &me, me);
20+
printf("you in thread (%p): %zu\n", &you, you);
21+
printf("you in thread (%p): %zu\n", &them, them);
22+
printf("us in thread (%p): %zu\n", &us, us);
23+
printf("errno in thread (%p): %d\n", &errno, errno);
24+
25+
return NULL;
26+
}
27+
28+
int main(void)
29+
{
30+
pthread_t new;
31+
int err;
32+
33+
me = 100;
34+
you = 999;
35+
them = 3;
36+
printf("me before create (%p): %zu\n", &me, me);
37+
printf("you before create (%p): %zu\n", &you, you);
38+
printf("them before create (%p): %zu\n", &them, them);
39+
printf("errno before create (%p): %d\n", &errno, errno);
40+
41+
err = pthread_create(&new, NULL, tf, (void *) 1);
42+
if (err < 0) {
43+
perror("pthread_create");
44+
exit(EXIT_FAILURE);
45+
}
46+
err = pthread_create(&new, NULL, tf, (void *) 2);
47+
if (err < 0) {
48+
perror("pthread_create");
49+
exit(EXIT_FAILURE);
50+
}
51+
52+
printf("me after create before join (%p): %zu\n", &me, me);
53+
printf("you after create before join (%p): %zu\n", &you, you);
54+
printf("them after create before join (%p): %zu\n", &them, them);
55+
printf("errno after create before join (%p): %d\n", &errno, errno);
56+
pthread_join(new, NULL);
57+
printf("me after join (%p): %zu\n", &me, me);
58+
printf("you after join (%p): %zu\n", &you, you);
59+
printf("them after join (%p): %zu\n", &them, them);
60+
printf("errno after join (%p): %d\n", &errno, errno);
61+
62+
return 0;
63+
}

tls/tsd.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <pthread.h>
4+
#include <unistd.h>
5+
#include <sys/types.h>
6+
7+
static pthread_key_t me_key;
8+
static pthread_key_t you_key;
9+
static pthread_key_t them_key;
10+
11+
static void *tf(void *arg)
12+
{
13+
pthread_setspecific(me_key, (const void *) 200);
14+
printf("me_key in thread (%p): %u, me value in thread: %zu\n", &me_key, me_key, (size_t) pthread_getspecific(me_key));
15+
printf("you_key in thread (%p): %u, you value in thread: %zu\n", &you_key, you_key, (size_t) pthread_getspecific(you_key));
16+
printf("them_key in thread (%p): %u, them value in thread: %zu\n", &them_key, them_key, (size_t) pthread_getspecific(them_key));
17+
18+
return NULL;
19+
}
20+
21+
int main(void)
22+
{
23+
pthread_t new;
24+
int err;
25+
26+
pthread_key_create(&me_key, NULL);
27+
pthread_key_create(&you_key, NULL);
28+
pthread_key_create(&them_key, NULL);
29+
30+
pthread_setspecific(me_key, (const void *) 100);
31+
pthread_setspecific(you_key, (const void *) 999);
32+
pthread_setspecific(them_key, (const void *) 3);
33+
printf("me_key before create (%p): %u, me value before create: %zu\n", &me_key, me_key, (size_t) pthread_getspecific(me_key));
34+
printf("you_key before create (%p): %u, me value before create: %zu\n", &you_key, you_key, (size_t) pthread_getspecific(you_key));
35+
printf("them_key before create (%p): %u, me value before create: %zu\n", &them_key, them_key, (size_t) pthread_getspecific(them_key));
36+
37+
err = pthread_create(&new, NULL, tf, NULL);
38+
if (err < 0) {
39+
perror("pthread_create");
40+
exit(EXIT_FAILURE);
41+
}
42+
43+
printf("me_key after create before join (%p): %u, me value after create before join: %zu\n", &me_key, me_key, (size_t) pthread_getspecific(me_key));
44+
printf("you_key after create before join (%p): %u, you value after create before join: %zu\n", &you_key, you_key, (size_t) pthread_getspecific(you_key));
45+
printf("them_key after create before join (%p): %u, them value beafter create before join: %zu\n", &them_key, them_key, (size_t) pthread_getspecific(them_key));
46+
pthread_join(new, NULL);
47+
printf("me_key after join (%p): %u, me value after join: %zu\n", &me_key, me_key, (size_t) pthread_getspecific(me_key));
48+
printf("you_key after join (%p): %u, you value after join: %zu\n", &you_key, you_key, (size_t) pthread_getspecific(you_key));
49+
printf("them_key after join (%p): %u, them value after join: %zu\n", &them_key, them_key, (size_t) pthread_getspecific(them_key));
50+
51+
/* This is really not required, but we call it for API completeness. */
52+
pthread_key_delete(me_key);
53+
pthread_key_delete(you_key);
54+
pthread_key_delete(them_key);
55+
56+
return 0;
57+
}

0 commit comments

Comments
 (0)