#include <readerwriterqueue.h>
Definition at line 52 of file readerwriterqueue.h.
◆ AllocationMode
◆ ReaderWriterQueue()
AE_NO_TSAN ReaderWriterQueue::ReaderWriterQueue |
( |
size_t |
maxSize = 15 | ) |
|
|
inlineexplicit |
Definition at line 81 of file readerwriterqueue.h.
85 assert(
MAX_BLOCK_SIZE >= 2 &&
"MAX_BLOCK_SIZE must be at least 2");
87 Block* firstBlock =
nullptr;
98 Block* lastBlock =
nullptr;
99 for (
size_t i = 0; i != initialBlockCount; ++i) {
101 if (block ==
nullptr) {
104 if (firstBlock ==
nullptr) {
108 lastBlock->next = block;
111 block->next = firstBlock;
116 if (firstBlock ==
nullptr) {
119 firstBlock->next = firstBlock;
AE_FORCEINLINE void fence(memory_order order) AE_NO_TSAN
weak_atomic< Block * > tailBlock
static Block * make_block(size_t capacity) AE_NO_TSAN
static AE_FORCEINLINE size_t ceilToPow2(size_t x)
weak_atomic< Block * > frontBlock
References ceilToPow2(), fence(), frontBlock, largestBlockSize, make_block(), MAX_BLOCK_SIZE, memory_order_sync, ReaderWriterQueue::Block::next, and tailBlock.
◆ ~ReaderWriterQueue()
AE_NO_TSAN ReaderWriterQueue::~ReaderWriterQueue |
( |
| ) |
|
|
inline |
◆ align_for()
Definition at line 490 of file readerwriterqueue.h.
492 const std::size_t alignment = std::alignment_of<U>::value;
493 return ptr + (alignment - (
reinterpret_cast<std::uintptr_t
>(ptr) % alignment)) % alignment;
◆ ceilToPow2()
static AE_FORCEINLINE size_t ReaderWriterQueue::ceilToPow2 |
( |
size_t |
x | ) |
|
|
inlinestaticprivate |
◆ enqueue()
◆ inner_enqueue()
Definition at line 381 of file readerwriterqueue.h.
392 size_t blockFront = tailBlock_->localFront;
393 size_t blockTail = tailBlock_->tail.load();
395 size_t nextBlockTail = (blockTail + 1) & tailBlock_->sizeMask;
396 if (nextBlockTail != blockFront || nextBlockTail != (tailBlock_->localFront = tailBlock_->front.load())) {
399 tailBlock_->data[blockTail]= element;
403 tailBlock_->tail = nextBlockTail;
416 Block* tailBlockNext = tailBlock_->next.load();
417 size_t nextBlockFront = tailBlockNext->localFront = tailBlockNext->front.load();
418 nextBlockTail = tailBlockNext->tail.load();
423 assert(nextBlockFront == nextBlockTail);
424 tailBlockNext->localFront = nextBlockFront;
426 tailBlockNext->data[nextBlockTail] = element;
428 tailBlockNext->tail = (nextBlockTail + 1) & tailBlockNext->sizeMask;
437 if (newBlock ==
nullptr) {
444 newBlock->data[0] = element;
445 assert(newBlock->front == 0);
446 newBlock->tail = newBlock->localTail = 1;
448 newBlock->next = tailBlock_->next.load();
449 tailBlock_->next = newBlock;
465 assert(
false &&
"Should be unreachable code");
References CanAlloc, CannotAlloc, ReaderWriterQueue::Block::data, fence(), ReaderWriterQueue::Block::front, frontBlock, largestBlockSize, weak_atomic< T >::load(), ReaderWriterQueue::Block::localFront, make_block(), MAX_BLOCK_SIZE, memory_order_acquire, memory_order_release, ReaderWriterQueue::Block::next, ReaderWriterQueue::Block::sizeMask, ReaderWriterQueue::Block::tail, and tailBlock.
Referenced by enqueue().
◆ make_block()
static Block* ReaderWriterQueue::make_block |
( |
size_t |
capacity | ) |
|
|
inlinestaticprivate |
Definition at line 532 of file readerwriterqueue.h.
535 UINT size =
sizeof(Block) + std::alignment_of<Block>::value - 1;
536 size +=
sizeof(
UINT8*) * capacity + std::alignment_of<UINT8*>::value - 1;
537 UINT8* newBlockRaw =
static_cast<UINT8*
>(std::malloc(size));
538 if (newBlockRaw ==
nullptr) {
542 UINT8* newBlockAligned = align_for<Block>(newBlockRaw);
543 UINT8* newBlockData = align_for<UINT8*>(newBlockAligned +
sizeof(Block));
544 return new (newBlockAligned) Block(capacity, newBlockRaw, newBlockData);
Referenced by inner_enqueue(), and ReaderWriterQueue().
◆ peek()
UINT8* ReaderWriterQueue::peek |
( |
| ) |
|
|
inline |
◆ pop()
bool ReaderWriterQueue::pop |
( |
| ) |
|
|
inline |
Definition at line 298 of file readerwriterqueue.h.
303 size_t blockTail = frontBlock_->localTail;
304 size_t blockFront = frontBlock_->front.load();
306 if (blockFront != blockTail || blockFront != (frontBlock_->localTail = frontBlock_->tail.load())) {
309 non_empty_front_block:
310 auto element =
reinterpret_cast<UINT8*
>(frontBlock_->data + blockFront *
sizeof(
UINT8));
313 blockFront = (blockFront + 1) & frontBlock_->sizeMask;
316 frontBlock_->front = blockFront;
318 else if (frontBlock_ !=
tailBlock.load()) {
321 blockTail = frontBlock_->localTail = frontBlock_->tail.load();
322 blockFront = frontBlock_->front.load();
325 if (blockFront != blockTail) {
326 goto non_empty_front_block;
330 Block* nextBlock = frontBlock_->next;
332 size_t nextBlockFront = nextBlock->front.load();
333 size_t nextBlockTail = nextBlock->localTail = nextBlock->tail.load();
336 assert(nextBlockFront != nextBlockTail);
344 auto element =
reinterpret_cast<UINT8*
>(frontBlock_->data + nextBlockFront *
sizeof(
UINT8*));
347 nextBlockFront = (nextBlockFront + 1) & frontBlock_->sizeMask;
350 frontBlock_->front = nextBlockFront;
AE_FORCEINLINE void compiler_fence(memory_order order) AE_NO_TSAN
References AE_UNUSED, compiler_fence(), ReaderWriterQueue::Block::data, fence(), ReaderWriterQueue::Block::front, frontBlock, weak_atomic< T >::load(), ReaderWriterQueue::Block::localTail, memory_order_acquire, memory_order_release, ReaderWriterQueue::Block::next, ReaderWriterQueue::Block::sizeMask, ReaderWriterQueue::Block::tail, and tailBlock.
Referenced by BlockingReaderWriterQueue::pop().
◆ size_approx()
size_t ReaderWriterQueue::size_approx |
( |
| ) |
const |
|
inline |
◆ try_dequeue()
bool ReaderWriterQueue::try_dequeue |
( |
UINT8 *& |
result | ) |
|
|
inline |
Definition at line 165 of file readerwriterqueue.h.
186 size_t blockTail = frontBlock_->localTail;
187 size_t blockFront = frontBlock_->front.load();
189 if (blockFront != blockTail || blockFront != (frontBlock_->localTail = frontBlock_->tail.load())) {
192 non_empty_front_block:
194 result = frontBlock_->data[blockFront];
197 blockFront = (blockFront + 1) & frontBlock_->sizeMask;
200 frontBlock_->front = blockFront;
202 else if (frontBlock_ !=
tailBlock.load()) {
206 blockTail = frontBlock_->localTail = frontBlock_->tail.load();
207 blockFront = frontBlock_->front.load();
210 if (blockFront != blockTail) {
212 goto non_empty_front_block;
216 Block* nextBlock = frontBlock_->next;
221 size_t nextBlockFront = nextBlock->front.load();
222 size_t nextBlockTail = nextBlock->localTail = nextBlock->tail.load();
227 assert(nextBlockFront != nextBlockTail);
236 result = frontBlock_->data [nextBlockFront];
240 nextBlockFront = (nextBlockFront + 1) & frontBlock_->sizeMask;
243 frontBlock_->front = nextBlockFront;
References AE_UNUSED, compiler_fence(), ReaderWriterQueue::Block::data, fence(), ReaderWriterQueue::Block::front, frontBlock, weak_atomic< T >::load(), ReaderWriterQueue::Block::localTail, memory_order_acquire, memory_order_release, ReaderWriterQueue::Block::next, ReaderWriterQueue::Block::sizeMask, ReaderWriterQueue::Block::tail, and tailBlock.
Referenced by BlockingReaderWriterQueue::try_dequeue(), BlockingReaderWriterQueue::wait_dequeue(), and BlockingReaderWriterQueue::wait_dequeue_timed().
◆ cachelineFiller
◆ frontBlock
◆ largestBlockSize
size_t ReaderWriterQueue::largestBlockSize |
|
private |
◆ tailBlock
◆ value_type
UINT8* ReaderWriterQueue::value_type |
The documentation for this class was generated from the following file: