Tervel  1.0.0
A collection of wait-free containers and algorithms.
Classes | Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes | Static Private Attributes | List of all members
tervel::containers::wf::RingBuffer< T > Class Template Reference

This is a non-blocking FIFO ring buffer design that was made wait-free by applying a progress assurance framework to it. More...

#include <ring_buffer.h>

Classes

class  BufferOp
 
class  DequeueOp
 
class  EnqueueOp
 
class  Helper
 
class  Value
 RingBuffer value class, values stored in the class must extend it. More...
 

Public Member Functions

 RingBuffer (size_t capacity)
 Ring Buffer constructor. More...
 
bool isFull ()
 Returns whether or not the ring buffer is full. More...
 
bool isFull (int64_t tail, int64_t head)
 Returns whether or not the ring buffer is full. More...
 
bool isEmpty ()
 Returns whether or not the ring buffer is empty. More...
 
bool isEmpty (int64_t tail, int64_t head)
 Returns whether or not the ring buffer is empty. More...
 
bool enqueue (T value)
 Enqueues the passed value into the buffer. More...
 
bool dequeue (T &value)
 Dequeues a value from the buffer. More...
 
std::string debug_string ()
 This function returns a string debugging information. More...
 

Private Member Functions

bool readValue (int64_t pos, uintptr_t &val)
 This function attempts to load a value from the buffer. More...
 
void getInfo (uintptr_t val, int64_t &val_seqid, bool &val_isValueType, bool &val_isMarked)
 This function is used to get information from a value read from the ring buffer. More...
 
int64_t nextHead ()
 performs a fetch-and-add on the head counter More...
 
int64_t getHead ()
 performs an atomic load on the head counter More...
 
int64_t casHead (int64_t &expected, int64_t new_val)
 
int64_t nextTail ()
 performs a fetch-and-add on the tail counter More...
 
int64_t getTail ()
 performs an atomic load on the tail counter More...
 
int64_t casTail (int64_t &expected, int64_t new_val)
 
int64_t nextSeqId (int64_t seqid)
 Returns the next seqid. More...
 
int64_t getPos (int64_t seqid)
 Returns the position a seqid belongs at. More...
 
bool backoff (int64_t pos, uintptr_t val)
 A backoff routine in the event of thread delay. More...
 
void atomic_delay_mark (int64_t pos)
 This function places a bitmark on the value held at address. More...
 
std::string debug_string (uintptr_t val)
 This prints out debugging information. More...
 

Static Private Member Functions

static uintptr_t EmptyType (int64_t seqid)
 Creates a uintptr_t that represents an EmptyType. More...
 
static int64_t getEmptyTypeSeqId (uintptr_t val)
 Returns the seqid encoded in the passed value. More...
 
static uintptr_t ValueType (T value, int64_t seqid)
 Creates a uintptr_t that represents an ValueType. More...
 
static T getValueType (uintptr_t val)
 Returns the value type from a uintptr. More...
 
static int64_t getValueTypeSeqId (uintptr_t val)
 Returns the seqid of the passed value. More...
 
static uintptr_t DelayMarkValue (uintptr_t val)
 Takes a uintptr_t and places a bitmark on the delayMark_lsb. More...
 
static bool isEmptyType (uintptr_t p)
 returns whether or not p represents an EmptyType More...
 
static bool isValueType (uintptr_t p)
 returns whether or not p represents an ValueType More...
 
static bool isDelayedMarked (uintptr_t p)
 returns whether or not p has a delay mark More...
 
static int64_t counterAction (std::atomic< int64_t > &counter, int64_t val)
 utility function for incrementing counter More...
 

Private Attributes

const int64_t capacity_
 
std::atomic< int64_t > head_ {0}
 
std::atomic< int64_t > tail_ {0}
 
std::unique_ptr< std::atomic< uintptr_t >[]> array_
 

Static Private Attributes

static const uintptr_t num_lsb = 3
 
static const uintptr_t delayMark_lsb = 0x1
 
static const uintptr_t emptytype_lsb = 0x2
 
static const uintptr_t oprec_lsb = 0x4
 
static const uintptr_t clear_lsb = 7
 

Detailed Description

template<typename T>
class tervel::containers::wf::RingBuffer< T >

This is a non-blocking FIFO ring buffer design that was made wait-free by applying a progress assurance framework to it.

If isDelayed never returns true then it will not use additional memory. However, if it does, then it will allocate some objects which are protected by hazard pointer protection.

This ring buffer is implemented on a statically sized array. It can only store pointer sized objects that extend the Value class. Further it reserves the 3 LSB for type identification, which makes it compatible only with 64 bit systems

It supports enqueue, dequeue, isFull, and isEmpty operations

Template Parameters
TThe type of information stored, must be a pointer and the class must extend RingBuffer::Value.

Constructor & Destructor Documentation

template<typename T >
tervel::containers::wf::RingBuffer< T >::RingBuffer ( size_t  capacity)

Ring Buffer constructor.

This constructs and initializes the ring buffer object

Parameters
capacitythe length of the internal array to allocate.

Member Function Documentation

template<typename T >
void tervel::containers::wf::RingBuffer< T >::atomic_delay_mark ( int64_t  pos)
private

This function places a bitmark on the value held at address.

This function places a bitmark on the value held at address by calling address->fetch_or(delayMark_lsb) and then it loads the new current value and assigns it to val.

Parameters
posThe position to perform the blind bitmark.
template<typename T >
bool tervel::containers::wf::RingBuffer< T >::backoff ( int64_t  pos,
uintptr_t  val 
)
private

A backoff routine in the event of thread delay.

This function is called in the event the value at position on the ringbuffer is lagging behind as a result of a delayed thread.

It calls tervel::util::backoff() and upon its return checks whether or the value at address has changed. If it has, it returns true, Else it returns false. If the value has changed the new value is assigned to val

Parameters
posThe pos val was read from
valThe last read value from address.
Returns
whether or not the val changed.
template<typename T >
int64_t tervel::containers::wf::RingBuffer< T >::casHead ( int64_t &  expected,
int64_t  new_val 
)
private
template<typename T >
int64_t tervel::containers::wf::RingBuffer< T >::casTail ( int64_t &  expected,
int64_t  new_val 
)
private
template<typename T >
int64_t tervel::containers::wf::RingBuffer< T >::counterAction ( std::atomic< int64_t > &  counter,
int64_t  val 
)
inlinestaticprivate

utility function for incrementing counter

contains internal checks on the returned value

Parameters
countercounter to increment
valvalue by which to increment the counter
Returns
returns the pre-incremented value of the tail counter.
template<typename T >
std::string tervel::containers::wf::RingBuffer< T >::debug_string ( )

This function returns a string debugging information.

This information includes Value at each potion, head, tail, capacity, and someother stuff.

Returns
debugging info string
template<typename T >
std::string tervel::containers::wf::RingBuffer< T >::debug_string ( uintptr_t  val)
private

This prints out debugging information.

This prints out debugging information.

Parameters
vala value loaded from a position on the buffer
Returns
a string representation the contents of val.
template<typename T >
uintptr_t tervel::containers::wf::RingBuffer< T >::DelayMarkValue ( uintptr_t  val)
inlinestaticprivate

Takes a uintptr_t and places a bitmark on the delayMark_lsb.

Takes a uintptr_t and places a bitmark on the delayMark_lsb

Parameters
valThe value to mark
Returns
A marked value
template<typename T >
bool tervel::containers::wf::RingBuffer< T >::dequeue ( T &  value)

Dequeues a value from the buffer.

This function attempts to dequeue a value. It returns false in the event the ring buffer is empty.

Parameters
valueA variable to store the dequeued value.
Returns
whether or not a value was dequeued.
template<typename T >
uintptr_t tervel::containers::wf::RingBuffer< T >::EmptyType ( int64_t  seqid)
inlinestaticprivate

Creates a uintptr_t that represents an EmptyType.

the uintptr_t is composed by seqid << num_lsb | emptytype_lsb

Parameters
seqidthe seqid for this EmptyType
Returns
Returns uintptr_t that represents an EmptyType
template<typename T >
bool tervel::containers::wf::RingBuffer< T >::enqueue ( value)

Enqueues the passed value into the buffer.

This function attempts to enqueue the passed value. It returns false in the event the ring buffer is full. Internally it assigned a sequence number to the value.

Parameters
valueThe value to enqueue.
Returns
whether or not the value was enqueued.
template<typename T >
int64_t tervel::containers::wf::RingBuffer< T >::getEmptyTypeSeqId ( uintptr_t  val)
inlinestaticprivate

Returns the seqid encoded in the passed value.

Returns the seqid encoded in the passed value

seqid = val >> num_lsb

Parameters
vala unitptr_t loaded from the buffer
Returns
its encoded seqid
template<typename T >
int64_t tervel::containers::wf::RingBuffer< T >::getHead ( )
private

performs an atomic load on the head counter

performs an atomic load on the head counter

Returns
returns the value of the head counter.
template<typename T >
void tervel::containers::wf::RingBuffer< T >::getInfo ( uintptr_t  val,
int64_t &  val_seqid,
bool &  val_isValueType,
bool &  val_isMarked 
)
private

This function is used to get information from a value read from the ring buffer.

This function is used to get information from a value read from the ring buffer. This information is then assigned to the arguments.

Parameters
vala value read from a position on the ring buffer
val_seqidThe seqid associated with val
val_isValueTypeWhether or not val is a ValueType
val_isMarkedWhether or not val has a delay mark.
template<typename T >
int64_t tervel::containers::wf::RingBuffer< T >::getPos ( int64_t  seqid)
private

Returns the position a seqid belongs at.

Returns the position a seqid belongs at, determined by seqid % capacity_

Parameters
seqidthe seqid
Returns
the position the seqid belongs at
template<typename T >
int64_t tervel::containers::wf::RingBuffer< T >::getTail ( )
private

performs an atomic load on the tail counter

performs an atomic load on the tail counter

Returns
returns the value of the tail counter.
template<typename T >
T tervel::containers::wf::RingBuffer< T >::getValueType ( uintptr_t  val)
inlinestaticprivate

Returns the value type from a uintptr.

clears any delayed marks then casts it to type T.

Parameters
valThe value to cast
Returns
val cast to type T
template<typename T >
int64_t tervel::containers::wf::RingBuffer< T >::getValueTypeSeqId ( uintptr_t  val)
inlinestaticprivate

Returns the seqid of the passed value.

Returns the seqid of the passed value, first it casts val to type T by calling getValyeType then it calls val->func_seqid();

Parameters
vala value read from the ring buffer that has been determined to be a ValueType
Returns
The values seqid
template<typename T >
bool tervel::containers::wf::RingBuffer< T >::isDelayedMarked ( uintptr_t  p)
inlinestaticprivate

returns whether or not p has a delay mark

returns whether or not p has a delay mark by examining the delayMark_lsb. If it is 1 then it is delayed

Parameters
pthe value to examine
Returns
whether or not it is has a delay mark.
template<typename T >
bool tervel::containers::wf::RingBuffer< T >::isEmpty ( )

Returns whether or not the ring buffer is empty.

Returns whether or not the ring buffer is empty.

Returns
Returns whether or not the ring buffer is empty.
template<typename T >
bool tervel::containers::wf::RingBuffer< T >::isEmpty ( int64_t  tail,
int64_t  head 
)

Returns whether or not the ring buffer is empty.

Returns whether or not the ring buffer is empty.

Parameters
tail
head
Returns
Returns whether or not the ring buffer is empty.
template<typename T >
bool tervel::containers::wf::RingBuffer< T >::isEmptyType ( uintptr_t  p)
inlinestaticprivate

returns whether or not p represents an EmptyType

returns whether or not p represents an EmptyType by examining the emptytype_lsb. If it is 1 then it is an EmptyType type.

Parameters
pthe value to examine
Returns
whether or not it is an EmptyType
template<typename T >
bool tervel::containers::wf::RingBuffer< T >::isFull ( )

Returns whether or not the ring buffer is full.

Returns whether or not the ring buffer is full.

Returns
Returns whether or not the ring buffer is full.
template<typename T >
bool tervel::containers::wf::RingBuffer< T >::isFull ( int64_t  tail,
int64_t  head 
)

Returns whether or not the ring buffer is full.

Returns whether or not the ring buffer is full.

Parameters
tail[description]
head[description]
Returns
Returns whether or not the ring buffer is full.
template<typename T >
bool tervel::containers::wf::RingBuffer< T >::isValueType ( uintptr_t  p)
inlinestaticprivate

returns whether or not p represents an ValueType

returns whether or not p represents an ValueType by examining the emptytype_lsb. If it is 0 then it is an ValueType type.

Parameters
pthe value to examine
Returns
whether or not it is an ValueType
template<typename T >
int64_t tervel::containers::wf::RingBuffer< T >::nextHead ( )
private

performs a fetch-and-add on the head counter

atomically increments the head

Returns
returns the pre-incremented value of the head counter.
template<typename T >
intptr_t tervel::containers::wf::RingBuffer< T >::nextSeqId ( int64_t  seqid)
private

Returns the next seqid.

Returns the next seqid, which is seqid+capacity_

Parameters
seqidThe current seqid
Returns
the next seqid
template<typename T >
int64_t tervel::containers::wf::RingBuffer< T >::nextTail ( )
private

performs a fetch-and-add on the tail counter

atomically increments the tail

Returns
returns the pre-incremented value of the tail counter.
template<typename T >
bool tervel::containers::wf::RingBuffer< T >::readValue ( int64_t  pos,
uintptr_t &  val 
)
private

This function attempts to load a value from the buffer.

This function encapsulates logic related to achieving hazard pointer protection on objects read from the buffer. Currently it does not protected type T objects, only Helper objects used in the progress assurance framework. If a Helper object is read it will return false, otherwise it will return a successful read.

Parameters
posthe position to load from
valthe variable to store the loaded value.
Returns
whether or not a load was successful
template<typename T >
uintptr_t tervel::containers::wf::RingBuffer< T >::ValueType ( value,
int64_t  seqid 
)
inlinestaticprivate

Creates a uintptr_t that represents an ValueType.

the uintptr_t is composed by casting value to a uintptr_t.

Internally it calls value->func_seqid(seqid) to set the seqid.

Parameters
valuea pointer type to enqueue
seqidthe sequence id assigned to this value
Returns
Returns uintptr_t that represents an ValueType

Member Data Documentation

template<typename T>
std::unique_ptr<std::atomic<uintptr_t>[]> tervel::containers::wf::RingBuffer< T >::array_
private
template<typename T>
const int64_t tervel::containers::wf::RingBuffer< T >::capacity_
private
template<typename T>
const uintptr_t tervel::containers::wf::RingBuffer< T >::clear_lsb = 7
staticprivate
template<typename T>
const uintptr_t tervel::containers::wf::RingBuffer< T >::delayMark_lsb = 0x1
staticprivate
template<typename T>
const uintptr_t tervel::containers::wf::RingBuffer< T >::emptytype_lsb = 0x2
staticprivate
template<typename T>
std::atomic<int64_t> tervel::containers::wf::RingBuffer< T >::head_ {0}
private
template<typename T>
const uintptr_t tervel::containers::wf::RingBuffer< T >::num_lsb = 3
staticprivate
template<typename T>
const uintptr_t tervel::containers::wf::RingBuffer< T >::oprec_lsb = 0x4
staticprivate
template<typename T>
std::atomic<int64_t> tervel::containers::wf::RingBuffer< T >::tail_ {0}
private

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