Program Listing for File MPMCQueue.h

↰ Return to documentation for file (ADS/concurrent/MPMCQueue.h)

/*--------------------------------------------------------------------------*/
/*---------------------------- File MPMCQueue.h ----------------------------*/
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/*----------------------------- DEFINITIONS --------------------------------*/
/*--------------------------------------------------------------------------*/

#ifndef __ADS_MPMCQueue
 #define __ADS_MPMCQueue
                      /* self-identification: #endif constant */

/*--------------------------------------------------------------------------*/
/*------------------------------ INCLUDES ----------------------------------*/
/*--------------------------------------------------------------------------*/

#include "ADS/Contract.h"

#include <algorithm>
#include <atomic>
#include <bit>
#include <cstddef>
#include <memory>
#include <new>
#include <utility>

/*--------------------------------------------------------------------------*/
/*--------------------------- NAMESPACE ------------------------------------*/
/*--------------------------------------------------------------------------*/

namespace ADS {

/*--------------------------------------------------------------------------*/
/*---------------------------- CLASS MPMCQueue -----------------------------*/
/*--------------------------------------------------------------------------*/

template< class T >
class MPMCQueue {

 struct Cell {
  std::atomic< std::size_t > seq;
  alignas( T ) unsigned char raw[ sizeof( T ) ];
  [[nodiscard]] T * item( void ) {
   return( std::launder( reinterpret_cast< T * >( raw ) ) );
   }
  };

/*--------------------------------------------------------------------------*/
 public:

 using Item = T;

 explicit MPMCQueue( std::size_t capacity );
 MPMCQueue( const MPMCQueue & ) = delete;
 MPMCQueue & operator=( const MPMCQueue & ) = delete;

 ~MPMCQueue();

 template< class ... Args >
 bool emplace( Args && ... args );

 bool push( const T & v ) { return( emplace( v ) ); }
 bool push( T && v ) { return( emplace( std::move( v ) ) ); }

 bool tryPop( T & x );

 [[nodiscard]] std::size_t size( void ) const;

 [[nodiscard]] bool empty( void ) const { return( size() == 0 ); }

 [[nodiscard]] std::size_t capacity( void ) const { return( f_mask + 1 ); }

/*--------------------------------------------------------------------------*/
 private:

 static constexpr std::size_t line = 64;

 alignas( 2 * line ) Cell * f_cell;
 std::size_t f_mask;
 alignas( 2 * line ) std::atomic< std::size_t > f_tail{ 0 };
 alignas( 2 * line ) std::atomic< std::size_t > f_head{ 0 };
 alignas( 2 * line ) char f_end = 0;
 };  // end( class MPMCQueue )

/*--------------------------------------------------------------------------*/

}  // end( namespace ADS )

/*--------------------------------------------------------------------------*/
/*-------------------------- IMPLEMENTATION --------------------------------*/
/*--------------------------------------------------------------------------*/

#include "ADS/concurrent/impl/MPMCQueue.tpp"

/*--------------------------------------------------------------------------*/

#endif  /* MPMCQueue.h included */

/*--------------------------------------------------------------------------*/
/*-------------------------- End File MPMCQueue.h --------------------------*/
/*--------------------------------------------------------------------------*/