80 lines · cpp
1// RUN: %clang_tsan %s -lstdc++ -o %t && %run %t 2>&1 | FileCheck %s2 3#include "test.h"4#include <pthread.h>5#include <signal.h>6#include <stdio.h>7 8#include <atomic>9#include <cassert>10#include <condition_variable>11#include <mutex>12 13std::mutex sampler_mutex; //dummy mutex to lock in the thread we spawn.14std::mutex done_mutex; // guards the cv and done variables.15std::condition_variable cv;16bool done = false;17std::atomic<bool> spin = true;18 19void *ThreadFunc(void *x) {20 while (spin) {21 // Lock the mutex22 std::lock_guard<std::mutex> guard(sampler_mutex);23 // Mutex is released at the end24 }25 26 return nullptr;27}28 29static void SigprofHandler(int signal, siginfo_t *info, void *context) {30 // Assuming we did some work, change the variable to let the main thread31 // know that we are done.32 {33 std::unique_lock<std::mutex> lck(done_mutex);34 done = true;35 cv.notify_one();36 }37}38 39int main() {40 alarm(60); // Kill the test if it hangs.41 42 // Install the signal handler43 struct sigaction sa;44 sa.sa_sigaction = SigprofHandler;45 sigemptyset(&sa.sa_mask);46 sa.sa_flags = SA_RESTART | SA_SIGINFO;47 if (sigaction(SIGPROF, &sa, 0) != 0) {48 fprintf(stderr, "failed to install signal handler\n");49 abort();50 }51 52 // Spawn a thread that will just loop and get the mutex lock:53 pthread_t thread;54 pthread_create(&thread, NULL, ThreadFunc, NULL);55 56 {57 // Lock the mutex before sending the signal58 std::lock_guard<std::mutex> guard(sampler_mutex);59 // From now on thread 1 will be waiting for the lock60 61 // Send the SIGPROF signal to thread.62 int r = pthread_kill(thread, SIGPROF);63 assert(r == 0);64 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 }72 73 // Wait for thread to prevent it from spinning on a released mutex.74 spin = false;75 pthread_join(thread, nullptr);76}77 78// CHECK-NOT: WARNING: ThreadSanitizer:79// CHECK: PASS80