17 setAllocator(allocator);
22 for (
size_t i = head_pos; i != tail_pos; ++i)
23 (&p_node[i & capacity_mask].data)->~T();
25 delete[] (
char*)p_node;
28 void setAllocator(
Allocator& allocator) { vector.setAllocator(allocator); }
30 void resize(
size_t capacity) {
31 capacity_mask = capacity - 1;
32 for (
size_t i = 1; i <=
sizeof(
void*) * 4; i <<= 1)
33 capacity_mask |= capacity_mask >> i;
34 capacity_value = capacity_mask + 1;
36 vector.resize(capacity);
37 p_node = vector.data();
39 for (
size_t i = 0; i < capacity; ++i) {
40 p_node[i].tail.store(i, std::memory_order_relaxed);
41 p_node[i].head.store(-1, std::memory_order_relaxed);
44 tail_pos.store(0, std::memory_order_relaxed);
45 head_pos.store(0, std::memory_order_relaxed);
48 size_t capacity()
const {
return capacity_value; }
51 size_t head = head_pos.load(std::memory_order_acquire);
52 return tail_pos.load(std::memory_order_relaxed) - head;
55 bool enqueue(
const T&& data) {
59 bool enqueue(
const T& data) {
61 size_t tail = tail_pos.load(std::memory_order_relaxed);
63 node = &p_node[tail & capacity_mask];
64 if (node->tail.load(std::memory_order_relaxed) != tail)
return false;
65 if ((tail_pos.compare_exchange_weak(tail, tail + 1,
66 std::memory_order_relaxed)))
69 new (&node->data) T(data);
70 node->head.store(tail, std::memory_order_release);
74 bool dequeue(T& result) {
76 size_t head = head_pos.load(std::memory_order_relaxed);
78 node = &p_node[head & capacity_mask];
79 if (node->head.load(std::memory_order_relaxed) != head)
return false;
80 if (head_pos.compare_exchange_weak(head, head + 1,
81 std::memory_order_relaxed))
86 node->tail.store(head + capacity_value, std::memory_order_release);
98 std::atomic<size_t> tail;
99 std::atomic<size_t> head;
103 size_t capacity_mask;
104 size_t capacity_value;
105 std::atomic<size_t> tail_pos;
106 std::atomic<size_t> head_pos;