BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlcc::FixedQueueIndexManager Class Reference

#include <bdlcc_fixedqueueindexmanager.h>

Public Types

enum  { k_MAX_CAPACITY = 1 << ((sizeof(int) * 8) - 2) , e_MAX_CAPACITY = k_MAX_CAPACITY }
 

Public Member Functions

 BSLMF_NESTED_TRAIT_DECLARATION (FixedQueueIndexManager, bslma::UsesBslmaAllocator)
 
 FixedQueueIndexManager (bsl::size_t capacity, bslma::Allocator *basicAllocator=0)
 
 ~FixedQueueIndexManager ()
 Destroy this object.
 
int reservePushIndex (unsigned int *generation, unsigned int *index)
 
void commitPushIndex (unsigned int generation, unsigned int index)
 
int reservePopIndex (unsigned int *generation, unsigned int *index)
 
void commitPopIndex (unsigned int generation, unsigned int index)
 
void disable ()
 
void enable ()
 Mark the queue as enabled.
 
int reservePopIndexForClear (unsigned int *disposedGeneration, unsigned int *disposedIndex, unsigned int endGeneration, unsigned int endIndex)
 
void abortPushIndexReservation (unsigned int generation, unsigned int index)
 
bool isEnabled () const
 
bsl::size_t length () const
 Return a snapshot of the number of items in the queue.
 
bsl::size_t capacity () const
 Return the maximum number of items that may be stored in the queue.
 
bsl::ostream & print (bsl::ostream &stream) const
 

Static Public Member Functions

static int circularDifference (unsigned int minuend, unsigned int subtrahend, unsigned int modulo)
 
static unsigned int numRepresentableGenerations (bsl::size_t capacity)
 

Detailed Description

This class implements a circular buffer of atomic state variables. These are intended to synchronize access to another (non-atomic) indexed data structure so that the other data structure can be used as a thread-enabled fixed-size queue.

See bdlcc_fixedqueueindexmanager

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
Enumerator
k_MAX_CAPACITY 
e_MAX_CAPACITY 

Constructor & Destructor Documentation

◆ FixedQueueIndexManager()

bdlcc::FixedQueueIndexManager::FixedQueueIndexManager ( bsl::size_t  capacity,
bslma::Allocator basicAllocator = 0 
)
explicit

Create an index manager for a circular buffer having the specified maximum capacity. Optionally specify a basicAllocator used to supply memory. If basicAllocator is 0, the currently installed default allocator is used. isEnabled will be true for the newly created index manager. The behavior is undefined unless 0 < capacity and capacity <= k_MAX_CAPACITY.

◆ ~FixedQueueIndexManager()

bdlcc::FixedQueueIndexManager::~FixedQueueIndexManager ( )

Member Function Documentation

◆ abortPushIndexReservation()

void bdlcc::FixedQueueIndexManager::abortPushIndexReservation ( unsigned int  generation,
unsigned int  index 
)

Release the specified index and make it available for use in the generation following the specified generation. The behavior is undefined unless the calling thread holds a reservation on generation and index, and clearPopIndex and then commitPushIndex have been repeatedly invoked with generation and index as input until no indices remain to clear. Note that this operation is used to facilitate removing all the elements in a circular buffer if an exception is thrown between reserving an index for pushing, and committing that index.

◆ BSLMF_NESTED_TRAIT_DECLARATION()

bdlcc::FixedQueueIndexManager::BSLMF_NESTED_TRAIT_DECLARATION ( FixedQueueIndexManager  ,
bslma::UsesBslmaAllocator   
)

◆ capacity()

bsl::size_t bdlcc::FixedQueueIndexManager::capacity ( ) const
inline

◆ circularDifference()

static int bdlcc::FixedQueueIndexManager::circularDifference ( unsigned int  minuend,
unsigned int  subtrahend,
unsigned int  modulo 
)
static

Return the difference between the specified minuend and the specified subtrahend (typically minuend - subtrahend) where minuend and subtrahend are both "circular values", meaning they are part of a non-euclidean number line where the value wrap around to 0 at the specified modulo. The difference between two circular values is the minimum of either the number of increments or the number of decrements to subtrahend that results in minuend (i.e., the minimum "distance" between the points on the number circle), where increments are a positive difference, and decrements are a negative difference. If the number of increments and number of decrements between minuend and subtrahend are equal, minuend - subtrahend is returned. For example, for a hypothetical compass, [0, 360):

circularDifference( 0, 359, 360) == 1
circularDifference( 359, 0, 360) == -1
circularDifference( 180, 0, 360) == 180
circularDifference( 0, 180, 360) == -180
static int circularDifference(unsigned int minuend, unsigned int subtrahend, unsigned int modulo)

The behavior is undefined unless minuend < modulo, subtrahend < modulo, and modulo <= INT_MAX + 1.

◆ commitPopIndex()

void bdlcc::FixedQueueIndexManager::commitPopIndex ( unsigned int  generation,
unsigned int  index 
)

Mark the specified index as available (empty) in the generation following the specified generation. The behavior is undefined unless generation and index' match those returned by a previous successful call to reservePopIndex (that has not previously been committed).

◆ commitPushIndex()

void bdlcc::FixedQueueIndexManager::commitPushIndex ( unsigned int  generation,
unsigned int  index 
)

Mark the specified index as occupied (full) in the specified generation. The behavior is undefined unless generation and index match those returned by a previous successful call to reservePushIndex (that has not previously been committed).

◆ disable()

void bdlcc::FixedQueueIndexManager::disable ( )

Mark the queue as disabled. Future calls to reservePushIndex will fail.

◆ enable()

void bdlcc::FixedQueueIndexManager::enable ( )

◆ isEnabled()

bool bdlcc::FixedQueueIndexManager::isEnabled ( ) const

Return true if the queue is enabled, and false if it is disabled.

◆ length()

bsl::size_t bdlcc::FixedQueueIndexManager::length ( ) const

◆ numRepresentableGenerations()

static unsigned int bdlcc::FixedQueueIndexManager::numRepresentableGenerations ( bsl::size_t  capacity)
static

Return the number of representable generations for a circular buffer of the specified capacity.

◆ print()

bsl::ostream & bdlcc::FixedQueueIndexManager::print ( bsl::ostream &  stream) const

Print a formatted string describing the current state of this object to the specified stream. If stream is not valid on entry, this operation has no effect. Note that this method describes the internal state of the buffer and is provided purely for debugging purposes.

◆ reservePopIndex()

int bdlcc::FixedQueueIndexManager::reservePopIndex ( unsigned int *  generation,
unsigned int *  index 
)

Reserve the next available index from which to dequeue an element from an (externally managed) circular buffer; load the specified index with the reserved index and load the specified generation with the current generation of the circular buffer. Return 0 on success, and a non-zero value if the queue is empty. If this method succeeds, other threads using this object may spin on the corresponding index state until commitPopIndex is called using the returned index and generation values; clients should call commitPopIndex quickly after this method returns, without performing any blocking operations. If this method fails the generation and index will be unmodified. The behavior is undefined if the current thread is already holding a reservation on either a push or pop index. Note that generation is necessary for invoking commitPopIndex but should not otherwise be used by the caller; the value reflects the of times the index in the circular buffer has been used.

◆ reservePopIndexForClear()

int bdlcc::FixedQueueIndexManager::reservePopIndexForClear ( unsigned int *  disposedGeneration,
unsigned int *  disposedIndex,
unsigned int  endGeneration,
unsigned int  endIndex 
)

If the next available index from which an element can be popped is before the specified endGeneration and endIndex then reserve that index for popping and load the specified disposedGeneration and disposedIndex with the generation and index of the reserved cell; otherwise this operation has no effect. Return 0 if an index was successfully reserved, and a non-zero value if the current pop index is at endIndex and endGeneration. The behavior is undefined unless endGeneration and endIndex refer to a cell that has been acquired for writing. Note that this operation is used to facilitate removing all the elements in a circular buffer if an exception is thrown between reserving an index for pushing, and committing that index – the intended usage is to call reservePopIndexForClear and then commitPopIndex, emptying all the cells up to the index that was reserved for writing, and then call abortPushIndexReservation on the reserved index.

◆ reservePushIndex()

int bdlcc::FixedQueueIndexManager::reservePushIndex ( unsigned int *  generation,
unsigned int *  index 
)

Reserve the next available index at which to enqueue an element in an (externally managed) circular buffer; load the specified index with the reserved index and load the specified generation with the current generation of the circular buffer. Return 0 on success, a negative value if the queue is disabled, and a positive value if the queue is full. If this method succeeds, other threads using this object may spin on the corresponding index state until commitPushIndex is called using the returned index and generation values; clients should call commitPushIndex quickly after this method returns, without performing any blocking operations. If this method fails the generation and index will be unmodified. The behavior is undefined if the current thread is already holding a reservation on either a push or pop index. Note that generation is necessary for invoking commitPushIndex but should not otherwise be used by the caller; the value reflects the number of times the index in the circular buffer has been used.


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