10#ifndef EIGEN_CXX11_THREADPOOL_RUNQUEUE_H_
11#define EIGEN_CXX11_THREADPOOL_RUNQUEUE_H_
37template <
typename Work,
unsigned kSize>
45 for (
unsigned i = 0;
i < kSize;
i++)
46 array_[
i].state.store(kEmpty, std::memory_order_relaxed);
54 unsigned front = front_.load(std::memory_order_relaxed);
55 Elem*
e = &array_[front & kMask];
56 uint8_t
s =
e->state.load(std::memory_order_relaxed);
58 !
e->state.compare_exchange_strong(
s, kBusy, std::memory_order_acquire))
60 front_.store(front + 1 + (kSize << 1), std::memory_order_relaxed);
62 e->state.store(kReady, std::memory_order_release);
69 unsigned front = front_.load(std::memory_order_relaxed);
70 Elem*
e = &array_[(front - 1) & kMask];
71 uint8_t
s =
e->state.load(std::memory_order_relaxed);
73 !
e->state.compare_exchange_strong(
s, kBusy, std::memory_order_acquire))
75 Work
w = std::move(
e->w);
76 e->state.store(kEmpty, std::memory_order_release);
77 front = ((front - 1) & kMask2) | (front & ~kMask2);
78 front_.store(front, std::memory_order_relaxed);
85 std::unique_lock<std::mutex> lock(mutex_);
86 unsigned back = back_.load(std::memory_order_relaxed);
87 Elem*
e = &array_[(back - 1) & kMask];
88 uint8_t
s =
e->state.load(std::memory_order_relaxed);
90 !
e->state.compare_exchange_strong(
s, kBusy, std::memory_order_acquire))
92 back = ((back - 1) & kMask2) | (back & ~kMask2);
93 back_.store(back, std::memory_order_relaxed);
95 e->state.store(kReady, std::memory_order_release);
101 if (
Empty())
return Work();
102 std::unique_lock<std::mutex> lock(mutex_);
103 unsigned back = back_.load(std::memory_order_relaxed);
104 Elem*
e = &array_[back & kMask];
105 uint8_t
s =
e->state.load(std::memory_order_relaxed);
107 !
e->state.compare_exchange_strong(
s, kBusy, std::memory_order_acquire))
109 Work
w = std::move(
e->w);
110 e->state.store(kEmpty, std::memory_order_release);
111 back_.store(back + 1 + (kSize << 1), std::memory_order_relaxed);
118 if (
Empty())
return 0;
119 std::unique_lock<std::mutex> lock(mutex_);
120 unsigned back = back_.load(std::memory_order_relaxed);
123 if (
size > 1) mid = back + (
size - 1) / 2;
126 for (;
static_cast<int>(mid - back) >= 0; mid--) {
127 Elem*
e = &array_[mid & kMask];
128 uint8_t
s =
e->state.load(std::memory_order_relaxed);
130 if (
s != kReady || !
e->state.compare_exchange_strong(
131 s, kBusy, std::memory_order_acquire))
139 result->push_back(std::move(
e->w));
140 e->state.store(kEmpty, std::memory_order_release);
144 back_.store(start + 1 + (kSize << 1), std::memory_order_relaxed);
150 unsigned Size()
const {
return SizeOrNotEmpty<true>(); }
154 bool Empty()
const {
return SizeOrNotEmpty<false>() == 0; }
164 static const unsigned kMask = kSize - 1;
165 static const unsigned kMask2 = (kSize << 1) - 1;
167 std::atomic<uint8_t> state;
183 std::atomic<unsigned> front_;
184 std::atomic<unsigned> back_;
190 template<
bool NeedSizeEstimate>
191 unsigned SizeOrNotEmpty()
const {
194 unsigned front = front_.load(std::memory_order_acquire);
197 unsigned back = back_.load(std::memory_order_acquire);
198 unsigned front1 = front_.load(std::memory_order_relaxed);
199 if (front != front1) {
201 std::atomic_thread_fence(std::memory_order_acquire);
204 if (NeedSizeEstimate) {
205 return CalculateSize(front, back);
208 unsigned maybe_zero = ((front ^ back) & kMask2);
211 eigen_assert((CalculateSize(front, back) == 0) == (maybe_zero == 0));
218 unsigned CalculateSize(
unsigned front,
unsigned back)
const {
219 int size = (front & kMask2) - (back & kMask2);
226 if (
size >
static_cast<int>(kSize))
size = kSize;
227 return static_cast<unsigned>(
size);
231 void operator=(
const RunQueue&) =
delete;
int n
Definition BiCGSTAB_simple.cpp:1
int i
Definition BiCGSTAB_step_by_step.cpp:9
Array< double, 1, 3 > e(1./3., 0.5, 2.)
#define eigen_plain_assert(x)
Definition Macros.h:1007
#define EIGEN_ALWAYS_INLINE
Definition Macros.h:932
#define eigen_assert(x)
Definition Macros.h:1037
RowVector3d w
Definition Matrix_resize_int.cpp:3
Scalar Scalar int size
Definition benchVecAdd.cpp:17
Work PushBack(Work w)
Definition RunQueue.h:84
unsigned PopBackHalf(std::vector< Work > *result)
Definition RunQueue.h:117
Work PopBack()
Definition RunQueue.h:100
Work PopFront()
Definition RunQueue.h:68
void Flush()
Definition RunQueue.h:157
Work PushFront(Work w)
Definition RunQueue.h:53
unsigned Size() const
Definition RunQueue.h:150
~RunQueue()
Definition RunQueue.h:49
bool Empty() const
Definition RunQueue.h:154
RunQueue()
Definition RunQueue.h:40
RealScalar s
Definition level1_cplx_impl.h:126
Namespace containing all symbols from the Eigen library.
Definition bench_norm.cpp:85