1 //===-- tsan_posix.cc -----------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file is a part of ThreadSanitizer (TSan), a race detector.
12 //===----------------------------------------------------------------------===//
13 #include "tsan_interface.h"
14 #include "tsan_test_util.h"
15 #include "gtest/gtest.h"
23 thread_key(pthread_key_t key, pthread_mutex_t *mtx, int val, int *cnt)
31 static void thread_secific_dtor(void *v) {
32 thread_key *k = (thread_key *)v;
33 EXPECT_EQ(pthread_mutex_lock(k->mtx), 0);
35 __tsan_write4(&k->cnt);
36 EXPECT_EQ(pthread_mutex_unlock(k->mtx), 0);
39 } else if (k->val == 43 || k->val == 44) {
41 EXPECT_EQ(pthread_setspecific(k->key, k), 0);
47 static void *dtors_thread(void *p) {
48 thread_key *k = (thread_key *)p;
49 EXPECT_EQ(pthread_setspecific(k->key, k), 0);
53 TEST(Posix, ThreadSpecificDtors) {
56 EXPECT_EQ(pthread_key_create(&key, thread_secific_dtor), 0);
58 EXPECT_EQ(pthread_mutex_init(&mtx, 0), 0);
61 k[0] = new thread_key(key, &mtx, 42, &cnt);
62 k[1] = new thread_key(key, &mtx, 43, &cnt);
63 k[2] = new thread_key(key, &mtx, 44, &cnt);
64 EXPECT_EQ(pthread_create(&th[0], 0, dtors_thread, k[0]), 0);
65 EXPECT_EQ(pthread_create(&th[1], 0, dtors_thread, k[1]), 0);
66 EXPECT_EQ(pthread_join(th[0], 0), 0);
67 EXPECT_EQ(pthread_create(&th[2], 0, dtors_thread, k[2]), 0);
68 EXPECT_EQ(pthread_join(th[1], 0), 0);
69 EXPECT_EQ(pthread_join(th[2], 0), 0);
70 EXPECT_EQ(pthread_key_delete(key), 0);
74 static __thread int local_var;
76 static void *local_thread(void *p) {
77 __tsan_write1(&local_var);
81 const int kThreads = 4;
82 pthread_t th[kThreads];
83 for (int i = 0; i < kThreads; i++)
84 EXPECT_EQ(pthread_create(&th[i], 0, local_thread,
85 (void*)((long)p - 1)), 0); // NOLINT
86 for (int i = 0; i < kThreads; i++)
87 EXPECT_EQ(pthread_join(th[i], 0), 0);
91 TEST(Posix, ThreadLocalAccesses) {
92 local_thread((void*)2);
101 static void *cond_thread(void *p) {
102 CondContext &ctx = *static_cast<CondContext*>(p);
104 EXPECT_EQ(pthread_mutex_lock(&ctx.m), 0);
105 EXPECT_EQ(ctx.data, 0);
107 EXPECT_EQ(pthread_cond_signal(&ctx.c), 0);
108 EXPECT_EQ(pthread_mutex_unlock(&ctx.m), 0);
110 EXPECT_EQ(pthread_mutex_lock(&ctx.m), 0);
111 while (ctx.data != 2)
112 EXPECT_EQ(pthread_cond_wait(&ctx.c, &ctx.m), 0);
113 EXPECT_EQ(pthread_mutex_unlock(&ctx.m), 0);
115 EXPECT_EQ(pthread_mutex_lock(&ctx.m), 0);
117 EXPECT_EQ(pthread_cond_broadcast(&ctx.c), 0);
118 EXPECT_EQ(pthread_mutex_unlock(&ctx.m), 0);
123 TEST(Posix, CondBasic) {
125 EXPECT_EQ(pthread_mutex_init(&ctx.m, 0), 0);
126 EXPECT_EQ(pthread_cond_init(&ctx.c, 0), 0);
129 EXPECT_EQ(pthread_create(&th, 0, cond_thread, &ctx), 0);
131 EXPECT_EQ(pthread_mutex_lock(&ctx.m), 0);
132 while (ctx.data != 1)
133 EXPECT_EQ(pthread_cond_wait(&ctx.c, &ctx.m), 0);
135 EXPECT_EQ(pthread_mutex_unlock(&ctx.m), 0);
136 EXPECT_EQ(pthread_cond_broadcast(&ctx.c), 0);
138 EXPECT_EQ(pthread_mutex_lock(&ctx.m), 0);
139 while (ctx.data != 3)
140 EXPECT_EQ(pthread_cond_wait(&ctx.c, &ctx.m), 0);
141 EXPECT_EQ(pthread_mutex_unlock(&ctx.m), 0);
143 EXPECT_EQ(pthread_join(th, 0), 0);
144 EXPECT_EQ(pthread_cond_destroy(&ctx.c), 0);
145 EXPECT_EQ(pthread_mutex_destroy(&ctx.m), 0);