// possible to call ~T() and it may happen to use hazard pointers.
folly::hazptr::hazptr_holder hptr;
Segment* s = hptr.get_protected(c_.head);
- return ryDequeueUntilMC(s, item, deadline);
+ return tryDequeueUntilMC(s, item, deadline);
}
}
- /** ryDequeueUntilSC */
+ /** tryDequeueUntilSC */
template <typename Clock, typename Duration>
FOLLY_ALWAYS_INLINE bool tryDequeueUntilSC(
Segment* s,
DCHECK_LT(t, (s->minTicket() + SegmentSize));
size_t idx = index(t);
Entry& e = s->entry(idx);
- if (!e.tryWaitUntil(deadline)) {
+ if (UNLIKELY(!tryDequeueWaitElem(e, t, deadline))) {
return false;
}
setConsumerTicket(t + 1);
/** tryDequeueUntilMC */
template <typename Clock, typename Duration>
- FOLLY_ALWAYS_INLINE bool ryDequeueUntilMC(
+ FOLLY_ALWAYS_INLINE bool tryDequeueUntilMC(
Segment* s,
T& item,
const std::chrono::time_point<Clock, Duration>& deadline) noexcept {
}
size_t idx = index(t);
Entry& e = s->entry(idx);
- if (!e.tryWaitUntil(deadline)) {
+ if (UNLIKELY(!tryDequeueWaitElem(e, t, deadline))) {
return false;
}
if (!c_.ticket.compare_exchange_weak(
}
}
+ /** tryDequeueWaitElem */
+ template <typename Clock, typename Duration>
+ FOLLY_ALWAYS_INLINE bool tryDequeueWaitElem(
+ Entry& e,
+ Ticket t,
+ const std::chrono::time_point<Clock, Duration>& deadline) noexcept {
+ while (true) {
+ if (LIKELY(e.tryWaitUntil(deadline))) {
+ return true;
+ }
+ if (t >= producerTicket()) {
+ return false;
+ }
+ asm_volatile_pause();
+ }
+ }
+
/** findSegment */
FOLLY_ALWAYS_INLINE
Segment* findSegment(Segment* s, const Ticket t) const noexcept {
template <typename Clock, typename Duration>
FOLLY_ALWAYS_INLINE bool tryWaitUntil(
const std::chrono::time_point<Clock, Duration>& deadline) noexcept {
- return flag_.try_wait_until(deadline);
+ // wait-options from benchmarks on contended queues:
+ auto const opt =
+ flag_.wait_options().spin_max(std::chrono::microseconds(10));
+ return flag_.try_wait_until(deadline, opt);
}
private:
Atom<Segment*> next_;
const Ticket min_;
bool marked_; // used for iterative deletion
- FOLLY_ALIGNED(Align)
- Entry b_[SegmentSize];
+ alignas(Align) Entry b_[SegmentSize];
public:
explicit Segment(const Ticket t)