173 std::atomic<size_t> sequence;
180 CACHE_ALIGNED(std::atomic<size_t>, rPtr);
181 CACHE_ALIGNED(std::atomic<size_t>, wPtr);
185 explicit BoundedQueue(
size_t maxSize) :
195 void initialize(
size_t maxSize)
197 if ( initialized )
return;
199 data =
new cell_t[dsize];
200 for (
size_t i = 0; i < maxSize; i++ )
201 data[i].sequence.store(i);
210 if ( initialized )
delete[] data;
213 size_t size()
const {
return (wPtr.load() - rPtr.load()); }
215 bool empty()
const {
return (rPtr.load() == wPtr.load()); }
217 bool try_insert(
const T& arg)
219 cell_t* cell =
nullptr;
220 size_t pos = wPtr.load(std::memory_order_relaxed);
222 cell = &data[pos % dsize];
223 size_t seq = cell->sequence.load(std::memory_order_acquire);
224 intptr_t diff = (intptr_t)seq - (intptr_t)pos;
226 if ( wPtr.compare_exchange_weak(pos, pos + 1, std::memory_order_relaxed) )
break;
228 else if ( 0 > diff ) {
233 pos = wPtr.load(std::memory_order_relaxed);
237 cell->sequence.store(pos + 1, std::memory_order_release);
241 bool try_remove(T& res)
243 cell_t* cell =
nullptr;
244 size_t pos = rPtr.load(std::memory_order_relaxed);
246 cell = &data[pos % dsize];
247 size_t seq = cell->sequence.load(std::memory_order_acquire);
248 intptr_t diff = (intptr_t)seq - (intptr_t)(pos + 1);
250 if ( rPtr.compare_exchange_weak(pos, pos + 1, std::memory_order_relaxed) )
break;
252 else if ( 0 > diff ) {
256 pos = rPtr.load(std::memory_order_relaxed);
260 cell->sequence.store(pos + dsize, std::memory_order_release);
268 if ( try_remove(res) ) {
279 struct CACHE_ALIGNED_T Node
281 std::atomic<Node*> next;
289 CACHE_ALIGNED(Node*, first);
290 CACHE_ALIGNED(Node*, last);
291 CACHE_ALIGNED(
Spinlock, consumerLock);
292 CACHE_ALIGNED(
Spinlock, producerLock);
298 first = last =
new Node();
303 while ( first !=
nullptr ) {
310 void insert(
const T& t)
312 Node* tmp =
new Node();
314 std::lock_guard<Spinlock> lock(producerLock);
319 bool try_remove(T& result)
321 std::lock_guard<Spinlock> lock(consumerLock);
322 Node* theFirst = first;
323 Node* theNext = first->next;
324 if ( theNext !=
nullptr ) {
325 result = theNext->data;
337 if ( try_remove(res) ) {