brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.0 KiB · 49b8536 Raw
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