24#ifndef CONTAINER_INTEGRALS_LOCKFREE_QUEUE_INCLUDED 
   25#define CONTAINER_INTEGRALS_LOCKFREE_QUEUE_INCLUDED 
  127template <typename T, T Null = std::numeric_limits<T>::max(), T Erased = 
Null,
 
  129          typename A = std::nullptr_t>
 
  132      std::is_integral<T>::value,
 
  133      "class `Integrals_lockfree_queue` requires an integral type as a first " 
  134      "template parameter");
 
  148  static constexpr T null_value = 
Null;
 
  149  static constexpr T erased_value = Erased;
 
  155    NO_MORE_ELEMENTS = -1,   
 
  157    NO_SPACE_AVAILABLE = -2  
 
  209    Iterator(
const Iterator &rhs);
 
  210    Iterator(Iterator &&rhs);
 
  214    Iterator &operator=(
const Iterator &rhs);
 
  215    Iterator &operator=(Iterator &&rhs);
 
  246    index_type m_current{std::numeric_limits<index_type>::max()};
 
  263      typename D = T, T 
M = 
Null, T F = Erased, 
typename J = I, 
typename B = A,
 
  264      std::enable_if_t<!std::is_same<B, std::nullptr_t>::value> * = 
nullptr>
 
  276      typename D = T, T 
M = 
Null, T F = Erased, 
typename J = I, 
typename B = A,
 
  277      std::enable_if_t<std::is_same<B, std::nullptr_t>::value> * = 
nullptr>
 
  504  template <
typename D = T, T 
M = 
Null, T F = Erased, 
typename J = I,
 
  505            typename B = A, 
typename Pred, std::enable_if_t<M != F> * = 
nullptr>
 
  560  size_t m_capacity{0};
 
  581template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  583    Integrals_lockfree_queue<T, Null, Erased, I, A> 
const &parent,
 
  584    Integrals_lockfree_queue<T, Null, Erased, I, A>::index_type position)
 
  585    : m_current{position}, m_parent{&parent} {}
 
  588template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  591    : m_current{rhs.m_current}, m_parent{rhs.m_parent} {}
 
  593template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  596    : m_current{rhs.m_current}, m_parent{rhs.m_parent} {
 
  597  rhs.m_current = std::numeric_limits<index_type>::max();
 
  598  rhs.m_parent = 
nullptr;
 
  601template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  610template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  615  this->m_parent = rhs.m_parent;
 
  616  rhs.m_current = std::numeric_limits<index_type>::max();
 
  617  rhs.m_parent = 
nullptr;
 
  621template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  624                                    A>::Iterator::operator++() {
 
  629template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  633                                    A>::Iterator::operator*() 
const {
 
  634  return this->m_parent->
m_array[this->m_parent->translate(this->m_current)];
 
  637template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  640                                    A>::Iterator::operator++(int) {
 
  641  auto to_return = (*this);
 
  646template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  650                                    A>::Iterator::operator->()
 const {
 
  651  return &(this->m_parent->m_array[this->m_parent->translate(this->m_current)]);
 
  654template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  656    T, 
Null, Erased, I, A>::Iterator::operator==(
Iterator const &rhs) 
const {
 
  657  return this->m_current == rhs.m_current && this->m_parent == rhs.m_parent;
 
  660template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  662    T, 
Null, Erased, I, A>::Iterator::operator!=(
Iterator const &rhs) 
const {
 
  663  return !((*this) == rhs);
 
  666template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  669  this->m_parent->m_array[this->m_parent->translate(this->m_current)].store(
 
  673template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  674template <
typename D, T 
M, T F, 
typename J, 
typename B,
 
  675          std::enable_if_t<!std::is_same<B, std::nullptr_t>::value> *>
 
  684template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  685template <
typename D, T 
M, T F, 
typename J, 
typename B,
 
  686          std::enable_if_t<std::is_same<B, std::nullptr_t>::value> *>
 
  689    : m_capacity{size}, m_array{size, null_value}, m_head{0}, m_tail{0} {}
 
  691template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  695  return this->m_array;
 
  698template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  701  for (
size_t idx = 0; idx != this->m_array.size(); ++idx)
 
  703  this->m_head->store(0);
 
  704  this->m_tail->store(0);
 
  707template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  710  auto head = this->m_head->load(std::memory_order_acquire) & clear_bit;
 
  711  auto tail = this->m_tail->load(std::memory_order_acquire) & clear_bit;
 
  715template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  718  auto tail = this->m_tail->load(std::memory_order_acquire) & clear_bit;
 
  719  auto head = this->m_head->load(std::memory_order_acquire) & clear_bit;
 
  720  return tail == head + this->capacity();
 
  723template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  726  return this->m_head->load(std::memory_order_seq_cst) & clear_bit;
 
  729template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  732  return this->m_tail->load(std::memory_order_seq_cst) & clear_bit;
 
  735template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  738  auto head = this->head();
 
  740      this->m_array[this->translate(head)].load(std::memory_order_seq_cst);
 
  741  return to_return == Erased ? 
Null : to_return;
 
  744template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  747  auto tail = this->tail();
 
  748  if (tail == 0) 
return Null;
 
  750      this->m_array[this->translate(tail - 1)].load(std::memory_order_seq_cst);
 
  751  return to_return == Erased ? 
Null : to_return;
 
  754template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  762template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  765        const_reference_type to_push) {
 
  766  return this->
push(to_push);
 
  769template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  773    auto head = this->m_head->load(std::memory_order_acquire) & clear_bit;
 
  774    auto tail = this->m_tail->load(std::memory_order_relaxed) & clear_bit;
 
  777      this->state() = enum_queue_state::NO_MORE_ELEMENTS;
 
  781    auto new_head = head + 1;
 
  783    if (this->m_head->compare_exchange_strong(
 
  786            std::memory_order_release)) {
 
  787      auto ¤t = this->m_array[this->translate(head)];
 
  794            current.compare_exchange_strong(
 
  796                std::memory_order_release)) {
 
  797          new_head &= clear_bit;  
 
  799          this->m_head->store(new_head, std::memory_order_seq_cst);
 
  800          if (value == Erased) {  
 
  806        std::this_thread::yield();
 
  809    std::this_thread::yield();
 
  814template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  818  assert(to_push != 
Null && to_push != Erased);
 
  821    auto tail = this->m_tail->load(std::memory_order_acquire) & clear_bit;
 
  822    auto head = this->m_head->load(std::memory_order_relaxed) & clear_bit;
 
  824    if (tail == head + this->m_capacity) {
 
  825      this->state() = enum_queue_state::NO_SPACE_AVAILABLE;
 
  829    auto new_tail = tail + 1;
 
  831    if (this->m_tail->compare_exchange_strong(
 
  834            std::memory_order_release)) {
 
  835      auto ¤t = this->m_array[this->translate(tail)];
 
  839        if (current.compare_exchange_strong(
 
  843                std::memory_order_acquire)) {
 
  844          new_tail &= clear_bit;  
 
  846          this->m_tail->store(new_tail, std::memory_order_seq_cst);
 
  849        std::this_thread::yield();
 
  853    std::this_thread::yield();
 
  858template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  861  return Iterator{*
this, this->head()};
 
  864template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  867  return Iterator{*
this, this->tail()};
 
  870template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  871template <
typename D, T 
M, T F, 
typename J, 
typename B, 
typename Pred,
 
  872          std::enable_if_t<M != F> *>
 
  877  for (
size_t idx = 0; idx != this->m_capacity; ++idx) {
 
  878    auto ¤t = this->m_array[idx];
 
  879    T value = current.load(std::memory_order_acquire);
 
  880    if (value != 
Null && value != Erased && predicate(value)) {
 
  881      if (current.compare_exchange_strong(value, Erased,
 
  882                                          std::memory_order_release)) {
 
  890template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  893  return this->m_capacity;
 
  896template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  898                                           A>::allocated_size()
 const {
 
  902template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  905  this->state() = enum_queue_state::SUCCESS;
 
  909template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  913  return this->state();
 
  916template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  920  for (
auto value : (*
this)) {
 
  921    out << (value == 
Null 
  930template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  933  return static_cast<size_t>(from % 
static_cast<index_type>(this->m_capacity));
 
  936template <
typename T, T Null, T Erased, 
typename I, 
typename A>
 
  938                                             A>::enum_queue_state &
 
Array of std::atomic elements of type T.
Definition: atomics_array.h:84
 
Iterator helper class to iterate over the queue staring at the virtual index pointed to by the head,...
Definition: integrals_lockfree_queue.h:198
 
Integrals_lockfree_queue< T, Null, Erased, I, A > const  * m_parent
The reference to the queue holding the elements.
Definition: integrals_lockfree_queue.h:248
 
T * pointer
Definition: integrals_lockfree_queue.h:202
 
Iterator & operator=(const Iterator &rhs)
Definition: integrals_lockfree_queue.h:603
 
index_type m_current
The position of the element this iterator is pointing to.
Definition: integrals_lockfree_queue.h:246
 
void set(value_type new_value)
Sets the value of the element the iterator is pointing to the given parameter.
Definition: integrals_lockfree_queue.h:667
 
T reference
Definition: integrals_lockfree_queue.h:203
 
virtual ~Iterator()=default
 
T value_type
Definition: integrals_lockfree_queue.h:201
 
std::ptrdiff_t difference_type
Definition: integrals_lockfree_queue.h:200
 
std::forward_iterator_tag iterator_category
Definition: integrals_lockfree_queue.h:204
 
Iterator(Integrals_lockfree_queue< T, Null, Erased, I, A > const &parent, index_type position)
 
Lock-free, fixed-size bounded, multiple-producer (MP), multiple-consumer (MC), circular FIFO queue fo...
Definition: integrals_lockfree_queue.h:130
 
Integrals_lockfree_queue< T, Null, Erased, I, A > & push(value_type to_push)
Takes the value passed on as a parameter, stores it in the virtual index pointed to by the tail of th...
Definition: integrals_lockfree_queue.h:816
 
Integrals_lockfree_queue(Integrals_lockfree_queue< T, Null, Erased, I, A > &&rhs)=delete
 
friend std::ostream & operator<<(std::ostream &out, Integrals_lockfree_queue< T, Null, Erased, I, A > const &in)
Definition: integrals_lockfree_queue.h:551
 
size_t erase_if(Pred predicate)
Erases values from the queue.
Definition: integrals_lockfree_queue.h:873
 
value_type pop()
Retrieves the value at the virtual index pointed by the head of the queue, clears that position,...
Definition: integrals_lockfree_queue.h:770
 
atomic_type m_tail
The virtual index being pointed to by the tail of the queue.
Definition: integrals_lockfree_queue.h:566
 
T const * const_pointer_type
Definition: integrals_lockfree_queue.h:138
 
unsigned long long index_type
Definition: integrals_lockfree_queue.h:144
 
Iterator begin() const
Retrieves an iterator instance that points to the same position pointed by the head of the queue.
Definition: integrals_lockfree_queue.h:860
 
size_t translate(index_type from) const
Translates a virtual monotonically increasing index into an index bounded to the queue capacity.
Definition: integrals_lockfree_queue.h:931
 
Integrals_lockfree_queue< T, Null, Erased, I, A > & clear_state()
Clears the error state of the last performed operations, if any.
Definition: integrals_lockfree_queue.h:904
 
size_t capacity() const
Returns the maximum number of elements allowed to coexist in the queue.
Definition: integrals_lockfree_queue.h:891
 
enum_queue_state get_state() const
Retrieves the error/success state of the last performed operation.
Definition: integrals_lockfree_queue.h:912
 
enum_queue_state
Definition: integrals_lockfree_queue.h:153
 
Integrals_lockfree_queue(Integrals_lockfree_queue< T, Null, Erased, I, A > const &rhs)=delete
 
index_type head() const
Retrieves the virtual index that the head of the queue is pointing to.
Definition: integrals_lockfree_queue.h:725
 
std::string to_string() const
Return this queue textual representation.
Definition: integrals_lockfree_queue.h:918
 
Integrals_lockfree_queue< T, Null, Erased, I, A > & operator=(Integrals_lockfree_queue< T, Null, Erased, I, A > &&rhs)=delete
 
static constexpr T null_value
Definition: integrals_lockfree_queue.h:148
 
bool is_full() const
Retrieves whether or not the tail of the queue is pointing to the same virtual index as the computed ...
Definition: integrals_lockfree_queue.h:716
 
value_type front() const
Retrieves the element at the front of the queue, i.e.
Definition: integrals_lockfree_queue.h:737
 
T * pointer_type
Definition: integrals_lockfree_queue.h:137
 
Integrals_lockfree_queue(size_t size)
Constructor allowing specific queue capacity.
Definition: integrals_lockfree_queue.h:688
 
bool is_empty() const
Retrieves whether or not the head and tail of the queue are pointing to the same virtual index.
Definition: integrals_lockfree_queue.h:708
 
T const & const_reference_type
Definition: integrals_lockfree_queue.h:140
 
std::atomic< T > element_type
Definition: integrals_lockfree_queue.h:143
 
value_type back() const
Retrieves the value of the position at the back of the queue, i.e.
Definition: integrals_lockfree_queue.h:746
 
size_t allocated_size() const
Returns the amount of bytes needed to store the maximum number of elements allowed to coexist in the ...
Definition: integrals_lockfree_queue.h:898
 
enum_queue_state & state() const
Retrieves the thread storage duration operation state variable.
Definition: integrals_lockfree_queue.h:939
 
T value_type
Definition: integrals_lockfree_queue.h:141
 
array_type m_array
The array of atomics in which the elements will be stored.
Definition: integrals_lockfree_queue.h:562
 
virtual ~Integrals_lockfree_queue()=default
Destructor for the class.
 
atomic_type m_head
The virtual index being pointed to by the head of the queue.
Definition: integrals_lockfree_queue.h:564
 
T & reference_type
Definition: integrals_lockfree_queue.h:139
 
Integrals_lockfree_queue< T, Null, Erased, I, A > & operator=(Integrals_lockfree_queue< T, Null, Erased, I, A > const &rhs)=delete
 
size_t m_capacity
The maximum allowed number of element allowed to coexist in the queue.
Definition: integrals_lockfree_queue.h:560
 
Iterator end() const
Retrieves an iterator instance that points to the same position pointed by the tail of the queue.
Definition: integrals_lockfree_queue.h:866
 
Integrals_lockfree_queue< T, Null, Erased, I, A > & operator>>(reference_type out)
Retrieves the value at the virtual index pointed by the head of the queue, clears that position,...
Definition: integrals_lockfree_queue.h:756
 
index_type tail() const
Retrieves the virtual index that the tail of the queue is pointing to.
Definition: integrals_lockfree_queue.h:731
 
T const const_value_type
Definition: integrals_lockfree_queue.h:142
 
void clear()
Sets all queue positions to Null and points the head and tail of the queue to the 0 virtual index.
Definition: integrals_lockfree_queue.h:699
 
Integrals_lockfree_queue(A &alloc, size_t size)
Constructor allowing a specific memory allocator and a specific queue capacity.
Definition: integrals_lockfree_queue.h:677
 
array_type & array()
Returns the underlying instance of memory::Atomics_array which holds the allocated memory for the arr...
Definition: integrals_lockfree_queue.h:694
 
Integrals_lockfree_queue< T, Null, Erased, I, A > & operator<<(const_reference_type to_push)
Takes the value passed on as a parameter, stores it in the virtual index pointed to by the tail of th...
Definition: integrals_lockfree_queue.h:764
 
Indexing provider that pads each of the array elements to the size of the CPU cache line,...
Definition: atomics_array_index_padding.h:57
 
ostream & operator<<(ostream &os, const Datetime &)
Definition: logger.cc:35
 
#define SUCCESS
Definition: completion_hash.h:27
 
#define M
Definition: ctype-tis620.cc:74
 
bool store(THD *thd, const Table *tp)
Stores the SDI for a table.
Definition: sdi.cc:607
 
static std::string to_string(const LEX_STRING &str)
Definition: lex_string.h:50
 
bool operator!=(const my_thread_handle &a, const my_thread_handle &b)
Definition: my_thread.h:158
 
bool operator==(const my_thread_handle &a, const my_thread_handle &b)
Definition: my_thread.h:151
 
borrowable::binary::Null Null
Definition: classic_protocol_binary.h:337
 
Definition: atomics_array.h:39
 
static mysql_service_status_t flush(reference_caching_cache cache) noexcept
Definition: component.cc:122
 
std::basic_ostringstream< char, std::char_traits< char >, ut::allocator< char > > ostringstream
Specialization of basic_ostringstream which uses ut::allocator.
Definition: ut0new.h:2875
 
std::set< Key, Compare, ut::allocator< Key > > set
Specialization of set which uses ut_allocator.
Definition: ut0new.h:2887
 
std::map< Key, Value, Compare, ut::allocator< std::pair< const Key, Value > > > map
Specialization of map which uses ut_allocator.
Definition: ut0new.h:2897
 
static bool push(mem_root_deque< Item * > *items, qep_row::mem_root_str &s, Item_null *nil)
Definition: opt_explain_traditional.cc:95
 
Ssl_acceptor_context_property_type & operator++(Ssl_acceptor_context_property_type &property_type)
Increment operator for Ssl_acceptor_context_type Used by iterator.
Definition: ssl_acceptor_context_data.cc:114