Go to the documentation of this file.00001
00002
00003
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
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
00032
00033
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
00068 TakeMutexLock(const TakeMutexLock&);
00069 const TakeMutexLock& operator=(const TakeMutexLock&);
00070 };
00071
00072
00073
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
00110 TakeSpinLock(const TakeSpinLock&);
00111 const TakeSpinLock& operator=(const TakeSpinLock&);
00112 };
00113
00114
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
00161 TakeRWSleepLock(const TakeRWSleepLock&);
00162 const TakeRWSleepLock& operator=(const TakeRWSleepLock&);
00163 };
00164
00165
00166
00167 struct InternalBlockingObjectData
00168 {
00169 InternalBlockingObjectData();
00170 ~InternalBlockingObjectData();
00171
00172 volatile int clearCount;
00173 volatile bool isSet;
00174 void *pdata;
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 }
00192
00193
00194 #ifndef LOCKS_INCLUDE_INLINE
00195 #define LOCKS_INCLUDE_INLINE
00196 #include "Locks.cpp"
00197 #endif
00198
00199
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