28template <
typename T, u
int64_t capacity_tp>
29 requires Is_power_of_two<capacity_tp>
32template <
typename T, u
int64_t capacity_tp>
33 requires Is_power_of_two<capacity_tp>
37 auto idx = get_next_index(m_head);
38 auto &slot = m_slots[idx];
44 std::unique_lock<Mutex_type>
lock(slot.validity_mt);
45 slot.producer_cv.wait(
lock,
46 [&]() {
return !slot.validity || stop_predicate(); });
51 slot.element = std::move(element);
55 slot.consumer_cv.notify_one();
59template <
typename T, u
int64_t capacity_tp>
60 requires Is_power_of_two<capacity_tp>
bool
62 return enqueue(std::move(element), []() {
return false; });
65template <
typename T, u
int64_t capacity_tp>
66 requires Is_power_of_two<capacity_tp>
70 auto idx = get_next_index(m_tail);
73 auto &slot = m_slots[idx];
74 std::unique_lock<Mutex_type>
lock(slot.validity_mt);
76 slot.consumer_cv.wait(
lock, [&stop_predicate, &slot]() {
77 return slot.validity || stop_predicate();
81 T elem = std::move(slot.element);
82 slot.validity =
false;
85 slot.producer_cv.notify_one();
86 return {std::move(elem),
true};
93template <
typename T, u
int64_t capacity_tp>
94 requires Is_power_of_two<capacity_tp>
bool
101 auto tail_idx = m_tail.load();
102 auto head_idx = m_head.load();
106template <
typename T, u
int64_t capacity_tp>
107 requires Is_power_of_two<capacity_tp>
109 std::atomic<std::size_t> ¤t) {
110 return current.fetch_add(1, std::memory_order_relaxed) % m_capacity;
113template <
typename T, u
int64_t capacity_tp>
114 requires Is_power_of_two<capacity_tp>
117 for (std::size_t idx = 0; idx < m_capacity; ++idx) {
118 m_slots[idx].producer_cv.notify_all();
119 m_slots[idx].consumer_cv.notify_all();
123template <
typename T, u
int64_t capacity_tp>
124 requires Is_power_of_two<capacity_tp>
126 auto head = m_head.load();
127 auto tail = m_tail.load();
143template <
typename T, u
int64_t capacity_tp>
144 requires Is_power_of_two<capacity_tp>
146 for (
auto &slot : m_slots) {
147 std::unique_lock<Mutex_type>
lock(slot.validity_mt);
148 slot.validity =
false;
void notify_all()
Signal shutdown: Notifies all blocked consumers.
std::size_t get_next_index(std::atomic< std::size_t > ¤t)
Atomically increments the given position (m_head for producers, m_tail for consumers) and returns the...
bool enqueue(Element_type &&element, P &&stop_predicate)
Enqueue (push) an element into the queue.
Sync_bounded_queue(Memory_resource={})
Construct the queue.
void reset()
Reset the queue: Clears all slots (sets validity=false, elements to default), resets m_head and m_tai...
std::pair< Element_type, bool > dequeue(P &&stop_predicate)
Dequeue an element from the queue.
std::size_t size() const
Estimates the queue size based on m_head and m_tail positions.
bool empty()
Check if the queue is empty.
#define P
Definition: dtoa.cc:620
#define T
Definition: jit_executor_value.cc:373
Provides atomic access in shared-exclusive modes.
Definition: shared_spin_lock.h:79
ValueType max(X &&first)
Definition: gtid.h:103
Definition: cache_line_size.h:31
static std::mutex lock
Definition: net_ns.cc:56