11 #pragma warning(disable: 4702)
19 assert((
capacity > 1) &&
"Ring queue capacity must be greater than one!");
20 assert(((
capacity & (
capacity - 1)) == 0) &&
"Ring queue capacity must be a power of two!");
22 memset(_pad0, 0,
sizeof(cache_line_pad));
23 memset(_pad1, 0,
sizeof(cache_line_pad));
24 memset(_pad2, 0,
sizeof(cache_line_pad));
25 memset(_pad3, 0,
sizeof(cache_line_pad));
28 for (
size_t i = 0; i <
capacity; ++i)
29 _buffer[i].sequence.store(i, std::memory_order_relaxed);
35 const size_t head = _head.load(std::memory_order_acquire);
36 const size_t tail = _tail.load(std::memory_order_acquire);
44 size_t head_sequence = _head.load(std::memory_order_relaxed);
48 Node* node = &_buffer[head_sequence & _mask];
49 size_t node_sequence = node->sequence.load(std::memory_order_acquire);
52 int64_t diff = (int64_t)node_sequence - (int64_t)head_sequence;
59 if (_head.compare_exchange_weak(head_sequence, head_sequence + 1, std::memory_order_relaxed))
62 swap(node->value, record);
65 node->sequence.store(head_sequence + 1, std::memory_order_release);
78 head_sequence = _head.load(std::memory_order_relaxed);
89 size_t tail_sequence = _tail.load(std::memory_order_relaxed);
93 Node* node = &_buffer[tail_sequence & _mask];
94 size_t node_sequence = node->sequence.load(std::memory_order_acquire);
97 int64_t diff = (int64_t)node_sequence - (int64_t)(tail_sequence + 1);
104 if (_tail.compare_exchange_weak(tail_sequence, tail_sequence + 1, std::memory_order_relaxed))
107 swap(record, node->value);
110 node->sequence.store(tail_sequence + _mask + 1, std::memory_order_release);
122 tail_sequence = _tail.load(std::memory_order_relaxed);
132 #if defined(_MSC_VER)
AsyncWaitFreeQueue(size_t capacity)
Default class constructor.
size_t size() const noexcept
Get ring queue size.
bool Enqueue(Record &record)
Enqueue and swap the logging record into the ring queue (multiple producers threads method)
bool Dequeue(Record &record)
Dequeue and swap the logging record from the ring queue (multiple consumers threads method)
size_t capacity() const noexcept
Get ring queue capacity.
C++ Logging project definitions.
void swap(Record &record1, Record &record2) noexcept