Skip to content

Commit 1a5bc7c

Browse files
authored
Fix flaky test: signal_in_mutex_lock.cpp (#92587)
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 af7467c commit 1a5bc7c

File tree

1 file changed

+20
-12
lines changed

1 file changed

+20
-12
lines changed

compiler-rt/test/tsan/signal_in_mutex_lock.cpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <signal.h>
66
#include <stdio.h>
77

8+
#include <atomic>
89
#include <cassert>
910
#include <condition_variable>
1011
#include <mutex>
@@ -13,9 +14,10 @@ std::mutex sampler_mutex; //dummy mutex to lock in the thread we spawn.
1314
std::mutex done_mutex; // guards the cv and done variables.
1415
std::condition_variable cv;
1516
bool done = false;
17+
std::atomic<bool> spin = true;
1618

1719
void *ThreadFunc(void *x) {
18-
while (true) {
20+
while (spin) {
1921
// Lock the mutex
2022
std::lock_guard<std::mutex> guard(sampler_mutex);
2123
// Mutex is released at the end
@@ -51,20 +53,26 @@ int main() {
5153
pthread_t thread;
5254
pthread_create(&thread, NULL, ThreadFunc, NULL);
5355

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
56+
{
57+
// Lock the mutex before sending the signal
58+
std::lock_guard<std::mutex> guard(sampler_mutex);
59+
// From now on thread 1 will be waiting for the lock
5760

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

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

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

7078
// CHECK-NOT: WARNING: ThreadSanitizer:

0 commit comments

Comments
 (0)