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 
00030 
00031     // -- Locking constructs
00032 
00033     //used by MutexLock
00034     struct InternalMutexLockData
00035     {
00036         void *crit;
00037     };
00038 
00040     class MutexLock: public ReferenceCountedData<InternalMutexLockData>
00041     {
00042     public:
00043         MutexLock();
00044         ~MutexLock();
00045 
00046         friend class TakeMutexLock;
00047     };
00048 
00050     class TakeMutexLock
00051     {
00052     public:
00054         TakeMutexLock(MutexLock &critSection, bool takeNow=true);
00056         ~TakeMutexLock();
00057 
00059         void Take();
00061         void Leave();
00062 
00063     private:
00064         MutexLock crit;
00065         bool taken;
00066 
00067         //you cannot duplicate this
00068         TakeMutexLock(const TakeMutexLock&);
00069         const TakeMutexLock& operator=(const TakeMutexLock&);
00070     };
00071 
00072 
00073     //used by SpinLock
00074     struct InternalSpinLockData
00075     {
00076         volatile nuint taken;
00077         bool collision;
00078 
00079         inline InternalSpinLockData(): taken(0), collision(false)
00080             {}
00081     };
00082 
00084     class SpinLock: public ReferenceCountedData<InternalSpinLockData>
00085     {
00086         friend class TakeSpinLock;
00087     };
00088 
00090     class TakeSpinLock
00091     {
00092     public:
00094         inline TakeSpinLock(SpinLock &slock, bool takeNow=true): locker(slock), taken(false)
00095             { if (takeNow) Take(); }
00097         inline ~TakeSpinLock()
00098             { Leave(); }
00099 
00101         inline void Take();
00103         inline void Leave();
00104 
00105     private:
00106         SpinLock locker;
00107         bool taken;
00108 
00109         //you cannot duplicate this
00110         TakeSpinLock(const TakeSpinLock&);
00111         const TakeSpinLock& operator=(const TakeSpinLock&);
00112     };
00113 
00114     //used by RWSleepLock
00115     struct InternalRWSleepLockData
00116     {
00117         volatile nuint readerCount;
00118         volatile nuint writerCount;
00119 
00120         std::multiset<nuint> readerThreadList;
00121         std::multiset<nuint> writerThreadList;
00122         SpinLock threadListLock;
00123 
00124         inline InternalRWSleepLockData(): readerCount(0), writerCount(0)
00125             {}
00126     };
00127 
00130     class RWSleepLock: public ReferenceCountedData<InternalRWSleepLockData>
00131     {
00132     public:
00133         friend class TakeRWSleepLock;
00134     };
00135 
00137     class TakeRWSleepLock
00138     {
00139     public:
00141         TakeRWSleepLock(RWSleepLock &rwsLock, bool writeAccessIfTakenNow=true, bool takeNow=true);
00143         ~TakeRWSleepLock();
00144 
00146         void TakeWrite();
00148         void LeaveWrite();
00149 
00151         void TakeRead();
00153         void LeaveRead();
00154 
00155     private:
00156         RWSleepLock lock;
00157 
00158         bool hasRead, hasWrite;
00159 
00160         //you cannot duplicate this
00161         TakeRWSleepLock(const TakeRWSleepLock&);
00162         const TakeRWSleepLock& operator=(const TakeRWSleepLock&);
00163     };
00164 
00165     // -- Signal-based blocking constructs
00166 
00167     struct InternalBlockingObjectData
00168     {
00169         InternalBlockingObjectData();
00170         ~InternalBlockingObjectData();
00171 
00172         volatile int clearCount;
00173         volatile bool isSet;
00174         void *pdata; //platform-specific container
00175     };
00176 
00178     class BlockingObject: public ReferenceCountedData<InternalBlockingObjectData>
00179     {
00180     public:
00182         void Clear();
00183 
00185         void Set();
00186 
00188         bool WaitUntilClear(bool setOnReturn=false, nuint timeToWait=0xffffffff);
00189     };
00190 
00191 } //namespace MPMA
00192 
00193 //include the templated and inline code
00194 #ifndef LOCKS_INCLUDE_INLINE
00195     #define LOCKS_INCLUDE_INLINE
00196     #include "Locks.cpp"
00197 #endif
00198 
00199 //include the platform-specific headers
00200 #if defined(_WIN32) || defined(_WIN64)
00201     #include "win32/LocksWin32.h"
00202 #else
00203     #include "linux/LocksLin32.h"
00204 #endif
00205 
00206 #endif //LOCKS_H_INCLUDED
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends