MPMA Framework 0.4
Locks.h
Go to the documentation of this file.
00001 
00002 //Luke Lenhart, 2007
00003 //See /docs/License.txt for details on how this code may be used.
00004 
00005 #include "Types.h"
00006 #include "ReferenceCount.h"
00007 
00008 #include <set>
00009 
00010 #ifndef LOCKS_H_INCLUDED
00011 #define LOCKS_H_INCLUDED
00012 
00013 namespace MPMA
00014 {
00015 
00016     //  -- Atomic Operations safe for multiprocessor operations
00017 
00019     void AtomicIntInc(volatile nuint *pint);
00020 
00022     void AtomicIntDec(volatile nuint *pint);
00023 
00025     nsint AtomicIntAdd(volatile nsint *pint, nsint addValue);
00026 
00028     bool AtomicCompareExchange(volatile nuint *pInt, nuint expectedValue, nuint newValue, volatile nuint &outResultValue);
00029 
00031     template <typename T> inline bool AtomicCompareExchange(T **ptrToReplace, T *ptrExpected, T *ptrToSet, T *&outResultValue) { return AtomicCompareExchange((nuint*)ptrToReplace, (nuint)ptrExpected, (nuint)ptrToSet, (nuint&)outResultValue); }
00032 
00033     // -- Locking constructs
00034 
00035     //used by MutexLock
00036     struct InternalMutexLockData
00037     {
00038         void *crit;
00039     };
00040 
00042     class MutexLock: public ReferenceCountedData<InternalMutexLockData>
00043     {
00044     public:
00045         MutexLock();
00046         ~MutexLock();
00047 
00048         friend class TakeMutexLock;
00049     };
00050 
00052     class TakeMutexLock
00053     {
00054     public:
00056         TakeMutexLock(MutexLock &critSection, bool takeNow=true);
00058         ~TakeMutexLock();
00059 
00061         void Take();
00063         void Leave();
00064 
00065     private:
00066         MutexLock crit;
00067         bool taken;
00068 
00069         //you cannot duplicate this
00070         TakeMutexLock(const TakeMutexLock&);
00071         const TakeMutexLock& operator=(const TakeMutexLock&);
00072     };
00073 
00074 
00075     //used by SpinLock
00076     struct InternalSpinLockData
00077     {
00078         volatile nuint taken;
00079         bool collision;
00080 
00081         inline InternalSpinLockData(): taken(0), collision(false)
00082             {}
00083     };
00084 
00086     class SpinLock: public ReferenceCountedData<InternalSpinLockData>
00087     {
00088         friend class TakeSpinLock;
00089     };
00090 
00092     class TakeSpinLock
00093     {
00094     public:
00096         inline TakeSpinLock(SpinLock &slock, bool takeNow=true): locker(slock), taken(false)
00097             { if (takeNow) Take(); }
00099         inline ~TakeSpinLock()
00100             { Leave(); }
00101 
00103         inline void Take();
00105         inline void Leave();
00106 
00107     private:
00108         SpinLock locker;
00109         bool taken;
00110 
00111         //you cannot duplicate this
00112         TakeSpinLock(const TakeSpinLock&);
00113         const TakeSpinLock& operator=(const TakeSpinLock&);
00114     };
00115 
00116     //used by RWSleepLock
00117     struct InternalRWSleepLockData
00118     {
00119         volatile nuint readerCount;
00120         volatile nuint writerCount;
00121 
00122         std::multiset<nuint> readerThreadList;
00123         std::multiset<nuint> writerThreadList;
00124         SpinLock threadListLock;
00125 
00126         inline InternalRWSleepLockData(): readerCount(0), writerCount(0)
00127             {}
00128     };
00129 
00132     class RWSleepLock: public ReferenceCountedData<InternalRWSleepLockData>
00133     {
00134     public:
00135         friend class TakeRWSleepLock;
00136     };
00137 
00139     class TakeRWSleepLock
00140     {
00141     public:
00143         TakeRWSleepLock(RWSleepLock &rwsLock, bool writeAccessIfTakenNow=true, bool takeNow=true);
00145         ~TakeRWSleepLock();
00146 
00148         void TakeWrite();
00150         void LeaveWrite();
00151 
00153         void TakeRead();
00155         void LeaveRead();
00156 
00157     private:
00158         RWSleepLock lock;
00159 
00160         bool hasRead, hasWrite;
00161 
00162         //you cannot duplicate this
00163         TakeRWSleepLock(const TakeRWSleepLock&);
00164         const TakeRWSleepLock& operator=(const TakeRWSleepLock&);
00165     };
00166 
00167     // -- Signal-based blocking constructs
00168 
00169     struct InternalBlockingObjectData
00170     {
00171         InternalBlockingObjectData();
00172         ~InternalBlockingObjectData();
00173 
00174         volatile int clearCount;
00175         volatile bool isSet;
00176         void *pdata; //platform-specific container
00177     };
00178 
00180     class BlockingObject: public ReferenceCountedData<InternalBlockingObjectData>
00181     {
00182     public:
00184         void Clear();
00185 
00187         void Set();
00188 
00190         bool WaitUntilClear(bool setOnReturn=false, nuint timeToWait=0xffffffff);
00191     };
00192 
00193 } //namespace MPMA
00194 
00195 //include the templated and inline code
00196 #ifndef LOCKS_INCLUDE_INLINE
00197     #define LOCKS_INCLUDE_INLINE
00198     #include "Locks.cpp"
00199 #endif
00200 
00201 //include the platform-specific headers
00202 #if defined(_WIN32) || defined(_WIN64)
00203     #include "win32/LocksWin32.h"
00204 #else
00205     #include "linux/LocksLin32.h"
00206 #endif
00207 
00208 #endif //LOCKS_H_INCLUDED
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends