1 // RUN: %clang_tsan %darwin_min_target_with_tls_support %s -o %t
2 // RUN: %clang_tsan %darwin_min_target_with_tls_support %s -DBUILD_SO -fPIC -o \
3 // RUN: %t-so.so -shared
4 // RUN: %run %t 2>&1 | FileCheck %s
5 // XFAIL: target={{.*netbsd.*}}
7 // Test that tsan cleans up dynamic TLS memory between reuse.
15 typedef volatile long *(* get_t
)();
18 void *Thread1(void *arg
) {
19 pthread_detach(pthread_self());
20 volatile long *x
= GetTls();
22 fprintf(stderr
, "stack: %p dtls: %p\n", &x
, x
);
23 barrier_wait(&barrier
);
27 void *Thread2(void *arg
) {
28 volatile long *x
= GetTls();
30 fprintf(stderr
, "stack: %p dtls: %p\n", &x
, x
);
34 int main(int argc
, char *argv
[]) {
36 snprintf(path
, sizeof(path
), "%s-so.so", argv
[0]);
38 void *handle
= dlopen(path
, RTLD_LAZY
);
39 if (!handle
) fprintf(stderr
, "%s\n", dlerror());
41 GetTls
= (get_t
)dlsym(handle
, "GetTls");
42 assert(dlerror() == 0);
44 barrier_init(&barrier
, 2);
46 pthread_create(&t
[0], 0, Thread1
, 0);
47 barrier_wait(&barrier
);
48 // Wait for actual thread termination without using pthread_join,
49 // which would synchronize threads.
51 pthread_create(&t
[1], 0, Thread2
, 0);
52 pthread_join(t
[1], 0);
53 fprintf(stderr
, "DONE\n");
57 __thread
long huge_thread_local_array
[1 << 17];
59 return &huge_thread_local_array
[0];
63 // CHECK-NOT: ThreadSanitizer: data race