1// RUN: %clang_tsan %s -lstdc++ -o %t && %run %t 2>&1 | FileCheck %s
2
3#include "test.h"
4#include <pthread.h>
5#include <signal.h>
6#include <stdio.h>
7
8#include <cassert>
9#include <condition_variable>
10#include <mutex>
11
12std::mutex sampler_mutex; //dummy mutex to lock in the thread we spawn.
13std::mutex done_mutex; // guards the cv and done variables.
14std::condition_variable cv;
15bool done = false;
16
17void *ThreadFunc(void *x) {
18 while (true) {
19 // Lock the mutex
20 std::lock_guard<std::mutex> guard(sampler_mutex);
21 // Mutex is released at the end
22 }
23
24 return nullptr;
25}
26
27static void SigprofHandler(int signal, siginfo_t *info, void *context) {
28 // Assuming we did some work, change the variable to let the main thread
29 // know that we are done.
30 {
31 std::unique_lock<std::mutex> lck(done_mutex);
32 done = true;
33 cv.notify_one();
34 }
35}
36
37int main() {
38 alarm(seconds: 60); // Kill the test if it hangs.
39
40 // Install the signal handler
41 struct sigaction sa;
42 sa.sa_sigaction = SigprofHandler;
43 sigemptyset(set: &sa.sa_mask);
44 sa.sa_flags = SA_RESTART | SA_SIGINFO;
45 if (sigaction(SIGPROF, act: &sa, oact: 0) != 0) {
46 fprintf(stderr, format: "failed to install signal handler\n");
47 abort();
48 }
49
50 // Spawn a thread that will just loop and get the mutex lock:
51 pthread_t thread;
52 pthread_create(newthread: &thread, NULL, start_routine: ThreadFunc, NULL);
53
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
57
58 // Send the SIGPROF signal to thread.
59 int r = pthread_kill(threadid: thread, SIGPROF);
60 assert(r == 0);
61
62 // Wait until signal handler sends the data.
63 std::unique_lock lk(done_mutex);
64 cv.wait(lk, [] { return done; });
65
66 // We got the done variable from the signal handler. Exiting successfully.
67 fprintf(stderr, format: "PASS\n");
68}
69
70// CHECK-NOT: WARNING: ThreadSanitizer:
71// CHECK: PASS
72

source code of compiler-rt/test/tsan/signal_in_mutex_lock.cpp