167 std::atomic<size_t> sequence;
174 CACHE_ALIGNED(std::atomic<size_t>, rPtr);
175 CACHE_ALIGNED(std::atomic<size_t>, wPtr);
179 explicit BoundedQueue(
size_t maxSize) :
189 void initialize(
size_t maxSize)
191 if ( initialized )
return;
193 data =
new cell_t[dsize];
194 for (
size_t i = 0; i < maxSize; i++ )
195 data[i].sequence.store(i);
204 if ( initialized )
delete[] data;
207 size_t size()
const {
return (wPtr.load() - rPtr.load()); }
209 bool empty()
const {
return (rPtr.load() == wPtr.load()); }
211 bool try_insert(
const T& arg)
213 cell_t* cell =
nullptr;
214 size_t pos = wPtr.load(std::memory_order_relaxed);
216 cell = &data[pos % dsize];
217 size_t seq = cell->sequence.load(std::memory_order_acquire);
218 intptr_t diff = (intptr_t)seq - (intptr_t)pos;
220 if ( wPtr.compare_exchange_weak(pos, pos + 1, std::memory_order_relaxed) )
break;
222 else if ( 0 > diff ) {
227 pos = wPtr.load(std::memory_order_relaxed);
231 cell->sequence.store(pos + 1, std::memory_order_release);
235 bool try_remove(T& res)
237 cell_t* cell =
nullptr;
238 size_t pos = rPtr.load(std::memory_order_relaxed);
240 cell = &data[pos % dsize];
241 size_t seq = cell->sequence.load(std::memory_order_acquire);
242 intptr_t diff = (intptr_t)seq - (intptr_t)(pos + 1);
244 if ( rPtr.compare_exchange_weak(pos, pos + 1, std::memory_order_relaxed) )
break;
246 else if ( 0 > diff ) {
250 pos = rPtr.load(std::memory_order_relaxed);
254 cell->sequence.store(pos + dsize, std::memory_order_release);
262 if ( try_remove(res) ) {
273 struct CACHE_ALIGNED_T Node
275 std::atomic<Node*> next;
283 CACHE_ALIGNED(Node*, first);
284 CACHE_ALIGNED(Node*, last);
285 CACHE_ALIGNED(
Spinlock, consumerLock);
286 CACHE_ALIGNED(
Spinlock, producerLock);
292 first = last =
new Node();
297 while ( first !=
nullptr ) {
304 void insert(
const T& t)
306 Node* tmp =
new Node();
308 std::lock_guard<Spinlock> lock(producerLock);
313 bool try_remove(T& result)
315 std::lock_guard<Spinlock> lock(consumerLock);
316 Node* theFirst = first;
317 Node* theNext = first->next;
318 if ( theNext !=
nullptr ) {
319 result = theNext->data;
331 if ( try_remove(res) ) {