brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.0 KiB · 28890dc Raw
79 lines · cpp
1#include "pseudo_barrier.h"2#include "thread.h"3#include <atomic>4#include <chrono>5#include <cinttypes>6#include <csignal>7#include <cstdio>8#include <cstdlib>9#include <cstring>10#include <mutex>11#include <thread>12#include <unistd.h>13#include <vector>14 15pseudo_barrier_t barrier;16std::mutex print_mutex;17std::atomic<bool> can_work;18thread_local volatile sig_atomic_t can_exit_now = false;19 20static void sigint_handler(int signo) {}21 22static void sigusr1_handler(int signo) {23  std::lock_guard<std::mutex> lock{print_mutex};24  std::printf("received SIGUSR1 on thread id: %" PRIx64 "\n", get_thread_id());25  can_exit_now = true;26}27 28static void thread_func() {29  // this ensures that all threads start before we stop30  pseudo_barrier_wait(barrier);31 32  // wait till the main thread indicates that we can go33  // (note: using a mutex here causes hang on FreeBSD when another thread34  // is suspended)35  while (!can_work.load())36    std::this_thread::sleep_for(std::chrono::milliseconds(50));37 38  // the mutex guarantees that two writes don't get interspersed39  {40    std::lock_guard<std::mutex> lock{print_mutex};41    std::printf("thread %" PRIx64 " running\n", get_thread_id());42  }43 44  // give other threads a fair chance to run45  for (int i = 0; i < 5; ++i) {46    std::this_thread::yield();47    std::this_thread::sleep_for(std::chrono::milliseconds(200));48    if (can_exit_now)49      return;50  }51 52  // if we didn't get signaled, terminate the program explicitly.53  _exit(0);54}55 56int main(int argc, char **argv) {57  int num = atoi(argv[1]);58 59  pseudo_barrier_init(barrier, num + 1);60 61  signal(SIGINT, sigint_handler);62  signal(SIGUSR1, sigusr1_handler);63 64  std::vector<std::thread> threads;65  for (int i = 0; i < num; ++i)66    threads.emplace_back(thread_func);67 68  // use the barrier to make sure all threads start before we stop69  pseudo_barrier_wait(barrier);70  std::raise(SIGINT);71 72  // allow the threads to work73  can_work.store(true);74 75  for (std::thread &thread : threads)76    thread.join();77  return 0;78}79