HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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) 2016 Dmitry Vyukov <dvyukov@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 #include <assert.h>
11 
12 #include "core/common/spin_pause.h"
14 
15 #include <mutex>
16 #include <atomic>
17 
18 namespace onnxruntime {
19 class Barrier {
20  public:
21  explicit Barrier(unsigned int count, bool spin = false)
22  : state_(count << 1), notified_(false), spin_(spin) {
23  assert(((count << 1) >> 1) == count);
24  }
25 #ifdef NDEBUG
26  ~Barrier() = default;
27 #else
29  assert((state_ >> 1) == 0);
30  }
31 #endif
32 
33  void Notify(unsigned int c = 1) {
34  unsigned int delta = c << 1;
35  unsigned int v = state_.fetch_sub(delta, std::memory_order_acq_rel) - delta;
36  if (v != 1) {
37  // Clear the lowest bit (waiter flag) and check that the original state
38  // value was not zero. If it was zero, it means that notify was called
39  // more times than the original count.
40  assert(((v + delta) & ~1) != 0);
41  return; // either count has not dropped to 0, or waiter is not waiting
42  }
43  std::unique_lock<OrtMutex> l(mu_);
44  assert(!notified_);
45  notified_ = true;
46  cv_.notify_all();
47  }
48 
49  void Wait() {
50  if (spin_) {
51  while ((state_ >> 1) != 0) {
53  }
54  } else {
55  unsigned int v = state_.fetch_or(1, std::memory_order_acq_rel);
56  if ((v >> 1) == 0)
57  return;
58  std::unique_lock<OrtMutex> l(mu_);
59  while (!notified_) {
60  cv_.wait(l);
61  }
62  }
63  }
64 
65  private:
66  OrtMutex mu_;
67  OrtCondVar cv_;
68  std::atomic<unsigned int> state_; // low bit is waiter flag
69  bool notified_;
70  const bool spin_;
71 };
72 
73 // Notification is an object that allows a user to to wait for another
74 // thread to signal a notification that an event has occurred.
75 //
76 // Multiple threads can wait on the same Notification object,
77 // but only one caller must call Notify() on the object.
80 };
81 } // namespace onnxruntime
void notify_all() noexcept
Definition: ort_mutex.h:138
const GLdouble * v
Definition: glcorearb.h:837
void wait(std::unique_lock< OrtMutex > &lk)
void Notify(unsigned int c=1)
Definition: Barrier.h:33
Barrier(unsigned int count, bool spin=false)
Definition: Barrier.h:21
GLint GLsizei count
Definition: glcorearb.h:405