Advertisement
homer512

barrier

Jul 20th, 2016
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.69 KB | None | 0 0
  1. #include <mutex>
  2. // using std::mutex, std::unique_lock
  3. #include <condition_variable>
  4. // using std::condition_variable
  5. #include <future>
  6. // using std::async, std::future
  7. #include <stdexcept>
  8. // using std::invalid_argument
  9. #include <array>
  10. // using std::array
  11.  
  12.  
  13. namespace {
  14.  
  15.   class barrier
  16.   {
  17.     std::mutex mutex;
  18.     int sequence_no, count;
  19.     const int total_count;
  20.     std::condition_variable condition;
  21.  
  22.   public:
  23.     explicit barrier(int total_count)
  24.       : sequence_no(), count(), total_count(total_count)
  25.     {
  26.       if(total_count < 1)
  27.         throw std::invalid_argument("barrier(total_count < 1)");
  28.     }
  29.     void wait()
  30.     {
  31.       std::unique_lock<std::mutex> lock(mutex);
  32.       if(! count) {
  33.         /* we are the first thread to arrive here. Let's set up the barrier */
  34.         ++sequence_no;
  35.         count = total_count;
  36.       }
  37.       if(--count) {
  38.         const int own_seq_no = sequence_no;
  39.         auto is_complete = [own_seq_no, this]() noexcept -> bool {
  40.           return this->count == 0 || this->sequence_no != own_seq_no;
  41.         };
  42.         condition.wait(lock, is_complete);
  43.       }
  44.       else {
  45. #      ifdef WAKE_AFTER
  46.         lock.unlock();
  47. #      endif
  48.         condition.notify_all();
  49.       }
  50.     }
  51.   };
  52.  
  53.  
  54.   void threadfun(barrier* shared_barrier, int iterations)
  55.   {
  56.     for(int i = 0; i < iterations; ++i)
  57.       shared_barrier->wait();
  58.   }
  59. }
  60.  
  61. int main()
  62. {
  63.   const int iterations = 1000;
  64.   constexpr int threads = 16;
  65.   std::array<std::future<void>, threads> futures;
  66.   barrier shared_barrier(threads);
  67.   for(std::future<void>& future: futures)
  68.     future = std::async(std::launch::async, threadfun, &shared_barrier,
  69.                         iterations);
  70.   for(std::future<void>& future: futures)
  71.     future.get();
  72. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement