23 #include <type_traits> 25 #include <boost/noncopyable.hpp> 35 template <
typename T,
template <
typename>
class Atom>
58 template <
typename T,
template <
typename>
class Atom = std::atomic>
62 "Element type must be nothrow default constructible");
66 "Element type must be trivially copyable");
79 return prevTicket !=
ticket;
91 return prevTicket !=
ticket;
100 : capacity_(capacity),
109 slots_[idx(ticket)].write(turn(ticket),
value);
118 slots_[idx(ticket)].write(turn(ticket),
value);
127 return slots_[idx(cursor.ticket)].tryRead(
dest, turn(cursor.ticket));
135 return slots_[idx(cursor.ticket)].waitAndTryRead(
dest, turn(cursor.ticket));
140 return Cursor(ticket_.load());
148 assert(skipFraction >= 0.0 && skipFraction <= 1.0);
151 uint64_t backStep = llround((1.0 - skipFraction) * capacity_);
154 backStep = std::max<uint64_t>(1, backStep);
157 backStep =
std::min(ticket, backStep);
159 return Cursor(ticket - backStep);
167 const std::unique_ptr<detail::RingBufferSlot<T, Atom>[]>
slots_;
172 return ticket % capacity_;
181 template <
typename T,
template <
typename>
class Atom>
187 Atom<uint32_t> cutoff(0);
188 sequencer_.waitForTurn(turn * 2, cutoff,
false);
191 sequencer_.completeTurn(turn * 2);
194 sequencer_.completeTurn(turn * 2 + 1);
199 uint32_t desired_turn = (turn + 1) * 2;
200 Atom<uint32_t> cutoff(0);
201 if (sequencer_.tryWaitForTurn(desired_turn, cutoff,
false) !=
208 return sequencer_.isTurn(desired_turn);
213 if (!sequencer_.isTurn((turn + 1) * 2)) {
219 return sequencer_.isTurn((turn + 1) * 2);
Cursor currentTail(double skipFraction=0.0) noexcept
bool waitAndTryRead(T &dest, const Cursor &cursor) noexcept
constexpr detail::Map< Move > move
—— Concurrent Priority Queue Implementation ——
requires E e noexcept(noexcept(s.error(std::move(e))))
uint32_t idx(uint64_t ticket) noexcept
static constexpr StringPiece ticket
LockFreeRingBuffer(uint32_t capacity) noexcept
void write(const uint32_t turn, T &value) noexcept
Cursor(uint64_t initialTicket) noexcept
constexpr auto data(C &c) -> decltype(c.data())
Cursor writeAndGetCursor(T &value) noexcept
std::is_trivially_copyable< T > is_trivially_copyable
const std::unique_ptr< detail::RingBufferSlot< T, Atom >[]> slots_
static const char *const value
TurnSequencer< Atom > sequencer_
uint32_t turn(uint64_t ticket) noexcept
bool moveBackward(uint64_t steps=1) noexcept
RingBufferSlot() noexcept
void write(T &value) noexcept
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
Cursor currentHead() noexcept
Returns a Cursor pointing to the first write that has not occurred yet.
bool waitAndTryRead(T &dest, uint32_t turn) noexcept
bool moveForward(uint64_t steps=1) noexcept
bool tryRead(T &dest, uint32_t turn) noexcept
bool tryRead(T &dest, const Cursor &cursor) noexcept