Shadowrun: Awakened 29 September 2011 - Build 871
Classes | Public Member Functions | Private Attributes
DataStructures::SingleProducerConsumer< SingleProducerConsumerType > Class Template Reference

A single producer consumer implementation without critical sections.

#include <SingleProducerConsumer.h>

Inheritance diagram for DataStructures::SingleProducerConsumer< SingleProducerConsumerType >:

List of all members.

Classes

struct  DataPlusPtr

Public Member Functions

void CancelReadLock (SingleProducerConsumerType *cancelToLocation)
 param[in] Which ReadLock() to cancel.
void CancelWriteLock (SingleProducerConsumerType *cancelToLocation)
bool CheckReadUnlockOrder (const SingleProducerConsumerType *data) const
void Clear (void)
 Clear is not thread-safe and none of the lock or unlock functions should be called while it is running.
bool ReadIsLocked (void) const
SingleProducerConsumerType * ReadLock (void)
void ReadUnlock (void)
 SingleProducerConsumer ()
int Size (void) const
SingleProducerConsumerType * WriteLock (void)
void WriteUnlock (void)
 Call when you are done writing to a block of memory returned by WriteLock()
 ~SingleProducerConsumer ()

Private Attributes

volatile DataPlusPtrreadAheadPointer
unsigned readCount
volatile DataPlusPtrreadPointer
volatile DataPlusPtrwriteAheadPointer
unsigned writeCount
volatile DataPlusPtrwritePointer

Detailed Description

template<class SingleProducerConsumerType>
class DataStructures::SingleProducerConsumer< SingleProducerConsumerType >

Definition at line 25 of file SingleProducerConsumer.h.


Constructor & Destructor Documentation

template<class SingleProducerConsumerType >
DataStructures::SingleProducerConsumer< SingleProducerConsumerType >::SingleProducerConsumer ( )

Definition at line 92 of file SingleProducerConsumer.h.

References _FILE_AND_LINE_, MINIMUM_LIST_SIZE, and RakAssert.

    {
        // Preallocate
        readPointer = RakNet::OP_NEW<DataPlusPtr>( _FILE_AND_LINE_ );
        writePointer=readPointer;
        readPointer->next = RakNet::OP_NEW<DataPlusPtr>( _FILE_AND_LINE_ );
        int listSize;
#ifdef _DEBUG
        RakAssert(MINIMUM_LIST_SIZE>=3);
#endif
        for (listSize=2; listSize < MINIMUM_LIST_SIZE; listSize++)
        {
            readPointer=readPointer->next;
            readPointer->next = RakNet::OP_NEW<DataPlusPtr>( _FILE_AND_LINE_ );
        }
        readPointer->next->next=writePointer; // last to next = start
        readPointer=writePointer;
        readAheadPointer=readPointer;
        writeAheadPointer=writePointer;
        readCount=writeCount=0;
    }
template<class SingleProducerConsumerType >
DataStructures::SingleProducerConsumer< SingleProducerConsumerType >::~SingleProducerConsumer ( )

Member Function Documentation

template<class SingleProducerConsumerType>
void DataStructures::SingleProducerConsumer< SingleProducerConsumerType >::CancelReadLock ( SingleProducerConsumerType *  cancelToLocation)

Definition at line 185 of file SingleProducerConsumer.h.

References RakAssert.

    {
#ifdef _DEBUG
        RakAssert(readPointer!=writePointer);
#endif
        readAheadPointer=(DataPlusPtr *)cancelToLocation;
    }
template<class SingleProducerConsumerType>
void DataStructures::SingleProducerConsumer< SingleProducerConsumerType >::CancelWriteLock ( SingleProducerConsumerType *  cancelToLocation)

Call if you don't want to write to a block of data from WriteLock() after all. Cancelling locks cancels all locks back up to the data passed. So if you lock twice and cancel using the first lock, the second lock is ignored

Parameters:
[in]cancelToLocationWhich WriteLock() to cancel.

Definition at line 148 of file SingleProducerConsumer.h.

    {
        writeAheadPointer=(DataPlusPtr *)cancelToLocation;
    }
template<class SingleProducerConsumerType>
bool DataStructures::SingleProducerConsumer< SingleProducerConsumerType >::CheckReadUnlockOrder ( const SingleProducerConsumerType *  data) const

Make sure that the pointer we done reading for the call to ReadUnlock is the right pointer. param[in] A previous pointer returned by ReadLock()

Definition at line 246 of file SingleProducerConsumer.h.

    {
        return const_cast<const SingleProducerConsumerType *>(&readPointer->object) == data;
    }
template<class SingleProducerConsumerType >
void DataStructures::SingleProducerConsumer< SingleProducerConsumerType >::Clear ( void  )

Definition at line 208 of file SingleProducerConsumer.h.

References _FILE_AND_LINE_, MINIMUM_LIST_SIZE, DataStructures::SingleProducerConsumer< SingleProducerConsumerType >::DataPlusPtr::next, RakNet::OP_DELETE(), and RakAssert.

    {
        // Shrink the list down to MINIMUM_LIST_SIZE elements
        volatile DataPlusPtr *next;
        writePointer=readPointer->next;

        int listSize=1;
        next=readPointer->next;
        while (next!=readPointer)
        {
            listSize++;
            next=next->next;
        }

        while (listSize-- > MINIMUM_LIST_SIZE)
        {
            next=writePointer->next;
#ifdef _DEBUG
            RakAssert(writePointer!=readPointer);
#endif
            RakNet::OP_DELETE((char*) writePointer, _FILE_AND_LINE_);
            writePointer=next;
        }

        readPointer->next=writePointer;
        writePointer=readPointer;
        readAheadPointer=readPointer;
        writeAheadPointer=writePointer;
        readCount=writeCount=0;
    }
template<class SingleProducerConsumerType >
bool DataStructures::SingleProducerConsumer< SingleProducerConsumerType >::ReadIsLocked ( void  ) const

Returns if ReadUnlock was called before ReadLock

Returns:
If the read is locked

Definition at line 253 of file SingleProducerConsumer.h.

template<class SingleProducerConsumerType >
SingleProducerConsumerType * DataStructures::SingleProducerConsumer< SingleProducerConsumerType >::ReadLock ( void  )

ReadLock must be immediately followed by ReadUnlock. These two functions must be called in the same thread.

Return values:
0No data is availble to read
Non-zeroThe data previously written to, in another thread, by WriteLock followed by WriteUnlock.

Definition at line 170 of file SingleProducerConsumer.h.

References DataStructures::SingleProducerConsumer< SingleProducerConsumerType >::DataPlusPtr::next.

    {
            if (readAheadPointer==writePointer ||
                readAheadPointer->readyToRead==false)
            {
                return 0;
            }

            volatile DataPlusPtr *last;
            last=readAheadPointer;
            readAheadPointer=readAheadPointer->next;
            return (SingleProducerConsumerType*)last;
    }
template<class SingleProducerConsumerType >
void DataStructures::SingleProducerConsumer< SingleProducerConsumerType >::ReadUnlock ( void  )

Signals that we are done reading the the data from the least recent call of ReadLock. At this point that pointer is no longer valid, and should no longer be read.

Definition at line 194 of file SingleProducerConsumer.h.

References RakAssert.

    {
#ifdef _DEBUG
        RakAssert(readAheadPointer!=readPointer); // If hits, then called ReadUnlock before ReadLock
        RakAssert(readPointer!=writePointer); // If hits, then called ReadUnlock when Read returns 0
#endif
        readCount++;

        // Allow writes to this memory block
        readPointer->readyToRead=false;
        readPointer=readPointer->next;
    }
template<class SingleProducerConsumerType >
int DataStructures::SingleProducerConsumer< SingleProducerConsumerType >::Size ( void  ) const

This function will estimate how many elements are waiting to be read. It's threadsafe enough that the value returned is stable, but not threadsafe enough to give accurate results.

Returns:
An ESTIMATE of how many data elements are waiting to be read

Definition at line 240 of file SingleProducerConsumer.h.

    {
        return writeCount-readCount;
    }
template<class SingleProducerConsumerType >
SingleProducerConsumerType * DataStructures::SingleProducerConsumer< SingleProducerConsumerType >::WriteLock ( void  )

WriteLock must be immediately followed by WriteUnlock. These two functions must be called in the same thread.

Returns:
A pointer to a block of data you can write to.

Definition at line 129 of file SingleProducerConsumer.h.

References _FILE_AND_LINE_, DataStructures::SingleProducerConsumer< SingleProducerConsumerType >::DataPlusPtr::next, and RakAssert.

    {
        if (writeAheadPointer->next==readPointer ||
            writeAheadPointer->next->readyToRead==true)
        {
            volatile DataPlusPtr *originalNext=writeAheadPointer->next;
            writeAheadPointer->next=RakNet::OP_NEW<DataPlusPtr>(_FILE_AND_LINE_);
            RakAssert(writeAheadPointer->next);
            writeAheadPointer->next->next=originalNext;
        }

        volatile DataPlusPtr *last;
        last=writeAheadPointer;
        writeAheadPointer=writeAheadPointer->next;

        return (SingleProducerConsumerType*) last;
    }
template<class SingleProducerConsumerType >
void DataStructures::SingleProducerConsumer< SingleProducerConsumerType >::WriteUnlock ( void  )

Definition at line 154 of file SingleProducerConsumer.h.

References RakAssert.

    {
        //  DataPlusPtr *dataContainer = (DataPlusPtr *)structure;

#ifdef _DEBUG
        RakAssert(writePointer->next!=readPointer);
        RakAssert(writePointer!=writeAheadPointer);
#endif

        writeCount++;
        // User is done with the data, allow send by updating the write pointer
        writePointer->readyToRead=true;
        writePointer=writePointer->next;
    }

Member Data Documentation

template<class SingleProducerConsumerType>
volatile DataPlusPtr* DataStructures::SingleProducerConsumer< SingleProducerConsumerType >::readAheadPointer [private]

Definition at line 84 of file SingleProducerConsumer.h.

template<class SingleProducerConsumerType>
unsigned DataStructures::SingleProducerConsumer< SingleProducerConsumerType >::readCount [private]

Definition at line 88 of file SingleProducerConsumer.h.

template<class SingleProducerConsumerType>
volatile DataPlusPtr* DataStructures::SingleProducerConsumer< SingleProducerConsumerType >::readPointer [private]

Definition at line 86 of file SingleProducerConsumer.h.

template<class SingleProducerConsumerType>
volatile DataPlusPtr* DataStructures::SingleProducerConsumer< SingleProducerConsumerType >::writeAheadPointer [private]

Definition at line 85 of file SingleProducerConsumer.h.

template<class SingleProducerConsumerType>
unsigned DataStructures::SingleProducerConsumer< SingleProducerConsumerType >::writeCount [private]

Definition at line 88 of file SingleProducerConsumer.h.

template<class SingleProducerConsumerType>
volatile DataPlusPtr* DataStructures::SingleProducerConsumer< SingleProducerConsumerType >::writePointer [private]

Definition at line 87 of file SingleProducerConsumer.h.


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

Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.

GNU Lesser General Public License 3 Sourceforge.net