Barrier.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2018 Rasmus Munk Larsen <rmlarsen@google.com>
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 // Barrier is an object that allows one or more threads to wait until
11 // Notify has been called a specified number of times.
12 
13 #ifndef EIGEN_CXX11_THREADPOOL_BARRIER_H
14 #define EIGEN_CXX11_THREADPOOL_BARRIER_H
15 
16 // IWYU pragma: private
17 #include "./InternalHeaderCheck.h"
18 
19 namespace Eigen {
20 
21 class Barrier {
22  public:
23  Barrier(unsigned int count) : state_(count << 1), notified_(false) {
24  eigen_plain_assert(((count << 1) >> 1) == count);
25  }
26  ~Barrier() { eigen_plain_assert((state_ >> 1) == 0); }
27 
28  void Notify() {
29  unsigned int v = state_.fetch_sub(2, std::memory_order_acq_rel) - 2;
30  if (v != 1) {
31  // Clear the lowest bit (waiter flag) and check that the original state
32  // value was not zero. If it was zero, it means that notify was called
33  // more times than the original count.
34  eigen_plain_assert(((v + 2) & ~1) != 0);
35  return; // either count has not dropped to 0, or waiter is not waiting
36  }
37  EIGEN_MUTEX_LOCK l(mu_);
39  notified_ = true;
40  cv_.notify_all();
41  }
42 
43  void Wait() {
44  unsigned int v = state_.fetch_or(1, std::memory_order_acq_rel);
45  if ((v >> 1) == 0) return;
46  EIGEN_MUTEX_LOCK l(mu_);
47  while (!notified_) {
48  cv_.wait(l);
49  }
50  }
51 
52  private:
53  EIGEN_MUTEX mu_;
54  EIGEN_CONDVAR cv_;
55  std::atomic<unsigned int> state_; // low bit is waiter flag
56  bool notified_;
57 };
58 
59 // Notification is an object that allows a user to to wait for another
60 // thread to signal a notification that an event has occurred.
61 //
62 // Multiple threads can wait on the same Notification object,
63 // but only one caller must call Notify() on the object.
66 };
67 
68 } // namespace Eigen
69 
70 #endif // EIGEN_CXX11_THREADPOOL_BARRIER_H
Array< int, Dynamic, 1 > v
Definition: Array_initializer_list_vector_cxx11.cpp:1
#define eigen_plain_assert(condition)
Definition: Assert.h:148
Definition: Barrier.h:21
bool notified_
Definition: Barrier.h:56
EIGEN_CONDVAR cv_
Definition: Barrier.h:54
void Wait()
Definition: Barrier.h:43
EIGEN_MUTEX mu_
Definition: Barrier.h:53
std::atomic< unsigned int > state_
Definition: Barrier.h:55
~Barrier()
Definition: Barrier.h:26
void Notify()
Definition: Barrier.h:28
Barrier(unsigned int count)
Definition: Barrier.h:23
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:70
Definition: Barrier.h:64
Notification()
Definition: Barrier.h:65