proxygen
folly::detail::SingleElementQueue< T, Atom > Struct Template Reference

#include <MPMCQueue.h>

Classes

struct  ImplByMove
 
struct  ImplByRelocation
 Tag classes for dispatching to enqueue/dequeue implementation. More...
 

Public Member Functions

 ~SingleElementQueue () noexcept
 
template<typename... Args, typename = typename std::enable_if< std::is_nothrow_constructible<T, Args...>::value>::type>
void enqueue (const uint32_t turn, Atom< uint32_t > &spinCutoff, const bool updateSpinCutoff, Args &&...args) noexcept
 enqueue using in-place noexcept construction More...
 
template<typename = typename std::enable_if< (folly::IsRelocatable<T>::value && std::is_nothrow_constructible<T>::value) || std::is_nothrow_constructible<T, T&&>::value>::type>
void enqueue (const uint32_t turn, Atom< uint32_t > &spinCutoff, const bool updateSpinCutoff, T &&goner) noexcept
 
template<class Clock >
bool tryWaitForEnqueueTurnUntil (const uint32_t turn, Atom< uint32_t > &spinCutoff, const bool updateSpinCutoff, const std::chrono::time_point< Clock > &when) noexcept
 
bool mayEnqueue (const uint32_t turn) const noexcept
 
void dequeue (uint32_t turn, Atom< uint32_t > &spinCutoff, const bool updateSpinCutoff, T &elem) noexcept
 
template<class Clock >
bool tryWaitForDequeueTurnUntil (const uint32_t turn, Atom< uint32_t > &spinCutoff, const bool updateSpinCutoff, const std::chrono::time_point< Clock > &when) noexcept
 
bool mayDequeue (const uint32_t turn) const noexcept
 

Private Member Functions

Tptr () noexcept
 
void destroyContents () noexcept
 
void enqueueImpl (const uint32_t turn, Atom< uint32_t > &spinCutoff, const bool updateSpinCutoff, T &&goner, ImplByMove) noexcept
 enqueue using nothrow move construction. More...
 
void enqueueImpl (const uint32_t turn, Atom< uint32_t > &spinCutoff, const bool updateSpinCutoff, T &&goner, ImplByRelocation) noexcept
 
void dequeueImpl (uint32_t turn, Atom< uint32_t > &spinCutoff, const bool updateSpinCutoff, T &elem, ImplByRelocation) noexcept
 
void dequeueImpl (uint32_t turn, Atom< uint32_t > &spinCutoff, const bool updateSpinCutoff, T &elem, ImplByMove) noexcept
 dequeue by nothrow move assignment. More...
 

Private Attributes

std::aligned_storage< sizeof(T), alignof(T)>::type contents_
 Storage for a T constructed with placement new. More...
 
TurnSequencer< Atomsequencer_
 Even turns are pushes, odd turns are pops. More...
 

Detailed Description

template<typename T, template< typename > class Atom>
struct folly::detail::SingleElementQueue< T, Atom >

SingleElementQueue implements a blocking queue that holds at most one item, and that requires its users to assign incrementing identifiers (turns) to each enqueue and dequeue operation. Note that the turns used by SingleElementQueue are doubled inside the TurnSequencer

Definition at line 38 of file MPMCQueue.h.

Constructor & Destructor Documentation

template<typename T , template< typename > class Atom>
folly::detail::SingleElementQueue< T, Atom >::~SingleElementQueue ( )
inlinenoexcept

Definition at line 1340 of file MPMCQueue.h.

References testing::Args(), folly::T, type, and folly::value().

1340  {
1341  if ((sequencer_.uncompletedTurnLSB() & 1) == 1) {
1342  // we are pending a dequeue, so we have a constructed item
1343  destroyContents();
1344  }
1345  }
TurnSequencer< Atom > sequencer_
Even turns are pushes, odd turns are pops.
Definition: MPMCQueue.h:1445

Member Function Documentation

template<typename T , template< typename > class Atom>
void folly::detail::SingleElementQueue< T, Atom >::dequeue ( uint32_t  turn,
Atom< uint32_t > &  spinCutoff,
const bool  updateSpinCutoff,
T elem 
)
inlinenoexcept

Definition at line 1405 of file MPMCQueue.h.

References type.

1409  {
1410  dequeueImpl(
1411  turn,
1412  spinCutoff,
1413  updateSpinCutoff,
1414  elem,
1415  typename std::conditional<
1417  ImplByRelocation,
1418  ImplByMove>::type());
1419  }
PskType type
void dequeueImpl(uint32_t turn, Atom< uint32_t > &spinCutoff, const bool updateSpinCutoff, T &elem, ImplByRelocation) noexcept
Definition: MPMCQueue.h:1494
template<typename T , template< typename > class Atom>
void folly::detail::SingleElementQueue< T, Atom >::dequeueImpl ( uint32_t  turn,
Atom< uint32_t > &  spinCutoff,
const bool  updateSpinCutoff,
T elem,
ImplByRelocation   
)
inlineprivatenoexcept

dequeue by destructing followed by relocation. This version is preferred, because as much work as possible can be done before waiting.

Definition at line 1494 of file MPMCQueue.h.

References folly::detail::TurnSequencer< Atom >::completeTurn(), and folly::detail::TurnSequencer< Atom >::waitForTurn().

1499  {
1500  try {
1501  elem.~T();
1502  } catch (...) {
1503  // unlikely, but if we don't complete our turn the queue will die
1504  }
1505  sequencer_.waitForTurn(turn * 2 + 1, spinCutoff, updateSpinCutoff);
1506  memcpy(&elem, &contents_, sizeof(T));
1507  sequencer_.completeTurn(turn * 2 + 1);
1508  }
folly::std T
TurnSequencer< Atom > sequencer_
Even turns are pushes, odd turns are pops.
Definition: MPMCQueue.h:1445
std::aligned_storage< sizeof(T), alignof(T)>::type contents_
Storage for a T constructed with placement new.
Definition: MPMCQueue.h:1442
template<typename T , template< typename > class Atom>
void folly::detail::SingleElementQueue< T, Atom >::dequeueImpl ( uint32_t  turn,
Atom< uint32_t > &  spinCutoff,
const bool  updateSpinCutoff,
T elem,
ImplByMove   
)
inlineprivatenoexcept

dequeue by nothrow move assignment.

Definition at line 1511 of file MPMCQueue.h.

References folly::detail::TurnSequencer< Atom >::completeTurn(), folly::gen::move, ptr, and folly::detail::TurnSequencer< Atom >::waitForTurn().

1516  {
1517  sequencer_.waitForTurn(turn * 2 + 1, spinCutoff, updateSpinCutoff);
1518  elem = std::move(*ptr());
1519  destroyContents();
1520  sequencer_.completeTurn(turn * 2 + 1);
1521  }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
TurnSequencer< Atom > sequencer_
Even turns are pushes, odd turns are pops.
Definition: MPMCQueue.h:1445
template<typename T , template< typename > class Atom>
void folly::detail::SingleElementQueue< T, Atom >::destroyContents ( )
inlineprivatenoexcept

Definition at line 1451 of file MPMCQueue.h.

References ptr.

1451  {
1452  try {
1453  ptr()->~T();
1454  } catch (...) {
1455  // g++ doesn't seem to have std::is_nothrow_destructible yet
1456  }
1457 #ifndef NDEBUG
1458  memset(&contents_, 'Q', sizeof(T));
1459 #endif
1460  }
folly::std T
std::aligned_storage< sizeof(T), alignof(T)>::type contents_
Storage for a T constructed with placement new.
Definition: MPMCQueue.h:1442
template<typename T , template< typename > class Atom>
template<typename... Args, typename = typename std::enable_if< std::is_nothrow_constructible<T, Args...>::value>::type>
void folly::detail::SingleElementQueue< T, Atom >::enqueue ( const uint32_t  turn,
Atom< uint32_t > &  spinCutoff,
const bool  updateSpinCutoff,
Args &&...  args 
)
inlinenoexcept

enqueue using in-place noexcept construction

Definition at line 1352 of file MPMCQueue.h.

References folly::T, type, and value.

Referenced by folly::detail::MPMCQueueBase< Derived< T, Atom, Dynamic > >::enqueueWithTicketBase().

1356  {
1357  sequencer_.waitForTurn(turn * 2, spinCutoff, updateSpinCutoff);
1358  new (&contents_) T(std::forward<Args>(args)...);
1359  sequencer_.completeTurn(turn * 2);
1360  }
folly::std T
TurnSequencer< Atom > sequencer_
Even turns are pushes, odd turns are pops.
Definition: MPMCQueue.h:1445
std::aligned_storage< sizeof(T), alignof(T)>::type contents_
Storage for a T constructed with placement new.
Definition: MPMCQueue.h:1442
template<typename T , template< typename > class Atom>
template<typename = typename std::enable_if< (folly::IsRelocatable<T>::value && std::is_nothrow_constructible<T>::value) || std::is_nothrow_constructible<T, T&&>::value>::type>
void folly::detail::SingleElementQueue< T, Atom >::enqueue ( const uint32_t  turn,
Atom< uint32_t > &  spinCutoff,
const bool  updateSpinCutoff,
T &&  goner 
)
inlinenoexcept

enqueue using move construction, either real (if is_nothrow_move_constructible) or simulated using relocation and default construction (if IsRelocatable and is_nothrow_constructible)

Definition at line 1370 of file MPMCQueue.h.

References folly::gen::move, type, and value.

1374  {
1375  enqueueImpl(
1376  turn,
1377  spinCutoff,
1378  updateSpinCutoff,
1379  std::move(goner),
1380  typename std::conditional<
1382  ImplByMove,
1383  ImplByRelocation>::type());
1384  }
PskType type
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
void enqueueImpl(const uint32_t turn, Atom< uint32_t > &spinCutoff, const bool updateSpinCutoff, T &&goner, ImplByMove) noexcept
enqueue using nothrow move construction.
Definition: MPMCQueue.h:1467
static const char *const value
Definition: Conv.cpp:50
template<typename T , template< typename > class Atom>
void folly::detail::SingleElementQueue< T, Atom >::enqueueImpl ( const uint32_t  turn,
Atom< uint32_t > &  spinCutoff,
const bool  updateSpinCutoff,
T &&  goner,
ImplByMove   
)
inlineprivatenoexcept

enqueue using nothrow move construction.

Definition at line 1467 of file MPMCQueue.h.

References folly::detail::TurnSequencer< Atom >::completeTurn(), folly::gen::move, folly::T, and folly::detail::TurnSequencer< Atom >::waitForTurn().

1472  {
1473  sequencer_.waitForTurn(turn * 2, spinCutoff, updateSpinCutoff);
1474  new (&contents_) T(std::move(goner));
1475  sequencer_.completeTurn(turn * 2);
1476  }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
folly::std T
TurnSequencer< Atom > sequencer_
Even turns are pushes, odd turns are pops.
Definition: MPMCQueue.h:1445
std::aligned_storage< sizeof(T), alignof(T)>::type contents_
Storage for a T constructed with placement new.
Definition: MPMCQueue.h:1442
template<typename T , template< typename > class Atom>
void folly::detail::SingleElementQueue< T, Atom >::enqueueImpl ( const uint32_t  turn,
Atom< uint32_t > &  spinCutoff,
const bool  updateSpinCutoff,
T &&  goner,
ImplByRelocation   
)
inlineprivatenoexcept

enqueue by simulating nothrow move with relocation, followed by default construction to a noexcept relocation.

Definition at line 1480 of file MPMCQueue.h.

References folly::detail::TurnSequencer< Atom >::completeTurn(), folly::T, and folly::detail::TurnSequencer< Atom >::waitForTurn().

1485  {
1486  sequencer_.waitForTurn(turn * 2, spinCutoff, updateSpinCutoff);
1487  memcpy(&contents_, &goner, sizeof(T));
1488  sequencer_.completeTurn(turn * 2);
1489  new (&goner) T();
1490  }
folly::std T
TurnSequencer< Atom > sequencer_
Even turns are pushes, odd turns are pops.
Definition: MPMCQueue.h:1445
std::aligned_storage< sizeof(T), alignof(T)>::type contents_
Storage for a T constructed with placement new.
Definition: MPMCQueue.h:1442
template<typename T , template< typename > class Atom>
bool folly::detail::SingleElementQueue< T, Atom >::mayDequeue ( const uint32_t  turn) const
inlinenoexcept

Definition at line 1436 of file MPMCQueue.h.

1436  {
1437  return sequencer_.isTurn(turn * 2 + 1);
1438  }
TurnSequencer< Atom > sequencer_
Even turns are pushes, odd turns are pops.
Definition: MPMCQueue.h:1445
template<typename T , template< typename > class Atom>
bool folly::detail::SingleElementQueue< T, Atom >::mayEnqueue ( const uint32_t  turn) const
inlinenoexcept

Definition at line 1401 of file MPMCQueue.h.

1401  {
1402  return sequencer_.isTurn(turn * 2);
1403  }
TurnSequencer< Atom > sequencer_
Even turns are pushes, odd turns are pops.
Definition: MPMCQueue.h:1445
template<typename T , template< typename > class Atom>
T* folly::detail::SingleElementQueue< T, Atom >::ptr ( )
inlineprivatenoexcept

Definition at line 1447 of file MPMCQueue.h.

1447  {
1448  return static_cast<T*>(static_cast<void*>(&contents_));
1449  }
folly::std T
std::aligned_storage< sizeof(T), alignof(T)>::type contents_
Storage for a T constructed with placement new.
Definition: MPMCQueue.h:1442
template<typename T , template< typename > class Atom>
template<class Clock >
bool folly::detail::SingleElementQueue< T, Atom >::tryWaitForDequeueTurnUntil ( const uint32_t  turn,
Atom< uint32_t > &  spinCutoff,
const bool  updateSpinCutoff,
const std::chrono::time_point< Clock > &  when 
)
inlinenoexcept

Waits until either: 1: the enqueue turn preceding the given dequeue turn has arrived 2: the given deadline has arrived Case 1 returns true, case 2 returns false.

Definition at line 1426 of file MPMCQueue.h.

References folly::when().

1430  {
1431  return sequencer_.tryWaitForTurn(
1432  turn * 2 + 1, spinCutoff, updateSpinCutoff, &when) !=
1434  }
TurnSequencer< Atom > sequencer_
Even turns are pushes, odd turns are pops.
Definition: MPMCQueue.h:1445
Future< Unit > when(bool p, F &&thunk)
Definition: Future-inl.h:2330
template<typename T , template< typename > class Atom>
template<class Clock >
bool folly::detail::SingleElementQueue< T, Atom >::tryWaitForEnqueueTurnUntil ( const uint32_t  turn,
Atom< uint32_t > &  spinCutoff,
const bool  updateSpinCutoff,
const std::chrono::time_point< Clock > &  when 
)
inlinenoexcept

Waits until either: 1: the dequeue turn preceding the given enqueue turn has arrived 2: the given deadline has arrived Case 1 returns true, case 2 returns false.

Definition at line 1391 of file MPMCQueue.h.

References folly::when().

1395  {
1396  return sequencer_.tryWaitForTurn(
1397  turn * 2, spinCutoff, updateSpinCutoff, &when) !=
1399  }
TurnSequencer< Atom > sequencer_
Even turns are pushes, odd turns are pops.
Definition: MPMCQueue.h:1445
Future< Unit > when(bool p, F &&thunk)
Definition: Future-inl.h:2330

Member Data Documentation

template<typename T , template< typename > class Atom>
std::aligned_storage<sizeof(T), alignof(T)>::type folly::detail::SingleElementQueue< T, Atom >::contents_
private

Storage for a T constructed with placement new.

Definition at line 1442 of file MPMCQueue.h.

template<typename T , template< typename > class Atom>
TurnSequencer<Atom> folly::detail::SingleElementQueue< T, Atom >::sequencer_
private

Even turns are pushes, odd turns are pops.

Definition at line 1445 of file MPMCQueue.h.


The documentation for this struct was generated from the following file: