Skip to content

Commit d4e3e17

Browse files
committed
Fix flaky test: signal_in_mutex_lock.cpp
Fix flaky test: the spawned thread keeps spinning on `sampler_mutex` which may be released before the thread is terminated based on termination ordering. My understanding of C++ semantics are that the program here is invalid: the destructors of global variables are invoked at the time of program termination, and it is the responsibility of the program to ensure that invoking those destructors is safe. rdar://126768628
1 parent 932bef2 commit d4e3e17

File tree

1 file changed

+19
-12
lines changed

1 file changed

+19
-12
lines changed

compiler-rt/test/tsan/signal_in_mutex_lock.cpp

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@ std::mutex sampler_mutex; //dummy mutex to lock in the thread we spawn.
1313
std::mutex done_mutex; // guards the cv and done variables.
1414
std::condition_variable cv;
1515
bool done = false;
16+
std::atomic<bool> spin = true;
1617

1718
void *ThreadFunc(void *x) {
18-
while (true) {
19+
while (spin) {
1920
// Lock the mutex
2021
std::lock_guard<std::mutex> guard(sampler_mutex);
2122
// Mutex is released at the end
@@ -51,20 +52,26 @@ int main() {
5152
pthread_t thread;
5253
pthread_create(&thread, NULL, ThreadFunc, NULL);
5354

54-
// Lock the mutex before sending the signal
55-
std::lock_guard<std::mutex> guard(sampler_mutex);
56-
// From now on thread 1 will be waiting for the lock
55+
{
56+
// Lock the mutex before sending the signal
57+
std::lock_guard<std::mutex> guard(sampler_mutex);
58+
// From now on thread 1 will be waiting for the lock
5759

58-
// Send the SIGPROF signal to thread.
59-
int r = pthread_kill(thread, SIGPROF);
60-
assert(r == 0);
60+
// Send the SIGPROF signal to thread.
61+
int r = pthread_kill(thread, SIGPROF);
62+
assert(r == 0);
6163

62-
// Wait until signal handler sends the data.
63-
std::unique_lock lk(done_mutex);
64-
cv.wait(lk, [] { return done; });
64+
// Wait until signal handler sends the data.
65+
std::unique_lock lk(done_mutex);
66+
cv.wait(lk, [] { return done; });
67+
68+
// We got the done variable from the signal handler. Exiting successfully.
69+
fprintf(stderr, "PASS\n");
70+
}
6571

66-
// We got the done variable from the signal handler. Exiting successfully.
67-
fprintf(stderr, "PASS\n");
72+
// Wait for thread to prevent it from spinning on a released mutex.
73+
spin = false;
74+
pthread_join(thread, nullptr);
6875
}
6976

7077
// CHECK-NOT: WARNING: ThreadSanitizer:

0 commit comments

Comments
 (0)