1*bef1ed93SStephan Aßmus /* MultiLocker.h */ 2*bef1ed93SStephan Aßmus /* 3*bef1ed93SStephan Aßmus Copyright 1999, Be Incorporated. All Rights Reserved. 4*bef1ed93SStephan Aßmus This file may be used under the terms of the Be Sample Code License. 5*bef1ed93SStephan Aßmus */ 6*bef1ed93SStephan Aßmus 7*bef1ed93SStephan Aßmus /* multiple-reader single-writer locking class */ 8*bef1ed93SStephan Aßmus 9*bef1ed93SStephan Aßmus #ifndef MULTI_LOCKER_H 10*bef1ed93SStephan Aßmus #define MULTI_LOCKER_H 11*bef1ed93SStephan Aßmus 12*bef1ed93SStephan Aßmus //#define TIMING 1 13*bef1ed93SStephan Aßmus 14*bef1ed93SStephan Aßmus #include <OS.h> 15*bef1ed93SStephan Aßmus 16*bef1ed93SStephan Aßmus const int32 LARGE_NUMBER = 100000; 17*bef1ed93SStephan Aßmus 18*bef1ed93SStephan Aßmus class MultiLocker { 19*bef1ed93SStephan Aßmus public: 20*bef1ed93SStephan Aßmus MultiLocker(const char* semaphoreBaseName); 21*bef1ed93SStephan Aßmus virtual ~MultiLocker(); 22*bef1ed93SStephan Aßmus 23*bef1ed93SStephan Aßmus status_t InitCheck(); 24*bef1ed93SStephan Aßmus 25*bef1ed93SStephan Aßmus //locking for reading or writing 26*bef1ed93SStephan Aßmus bool ReadLock(); 27*bef1ed93SStephan Aßmus bool WriteLock(); 28*bef1ed93SStephan Aßmus 29*bef1ed93SStephan Aßmus //unlocking after reading or writing 30*bef1ed93SStephan Aßmus bool ReadUnlock(); 31*bef1ed93SStephan Aßmus bool WriteUnlock(); 32*bef1ed93SStephan Aßmus 33*bef1ed93SStephan Aßmus //does the current thread hold a write lock ? 34*bef1ed93SStephan Aßmus bool IsWriteLocked(uint32 *stack_base = NULL, thread_id *thread = NULL); 35*bef1ed93SStephan Aßmus //in DEBUG mode returns whether the lock is held 36*bef1ed93SStephan Aßmus //in non-debug mode returns true 37*bef1ed93SStephan Aßmus bool IsReadLocked(); 38*bef1ed93SStephan Aßmus 39*bef1ed93SStephan Aßmus private: 40*bef1ed93SStephan Aßmus //functions for managing the DEBUG reader array 41*bef1ed93SStephan Aßmus void register_thread(); 42*bef1ed93SStephan Aßmus void unregister_thread(); 43*bef1ed93SStephan Aßmus 44*bef1ed93SStephan Aßmus status_t fInit; 45*bef1ed93SStephan Aßmus //readers adjust count and block on fReadSem when a writer 46*bef1ed93SStephan Aßmus //hold the lock 47*bef1ed93SStephan Aßmus int32 fReadCount; 48*bef1ed93SStephan Aßmus sem_id fReadSem; 49*bef1ed93SStephan Aßmus //writers adjust the count and block on fWriteSem 50*bef1ed93SStephan Aßmus //when readers hold the lock 51*bef1ed93SStephan Aßmus int32 fWriteCount; 52*bef1ed93SStephan Aßmus sem_id fWriteSem; 53*bef1ed93SStephan Aßmus //writers must acquire fWriterLock when acquiring a write lock 54*bef1ed93SStephan Aßmus int32 fLockCount; 55*bef1ed93SStephan Aßmus sem_id fWriterLock; 56*bef1ed93SStephan Aßmus int32 fWriterNest; 57*bef1ed93SStephan Aßmus 58*bef1ed93SStephan Aßmus thread_id fWriterThread; 59*bef1ed93SStephan Aßmus uint32 fWriterStackBase; 60*bef1ed93SStephan Aßmus 61*bef1ed93SStephan Aßmus int32 * fDebugArray; 62*bef1ed93SStephan Aßmus int32 fMaxThreads; 63*bef1ed93SStephan Aßmus 64*bef1ed93SStephan Aßmus #if TIMING 65*bef1ed93SStephan Aßmus uint32 rl_count; 66*bef1ed93SStephan Aßmus bigtime_t rl_time; 67*bef1ed93SStephan Aßmus uint32 ru_count; 68*bef1ed93SStephan Aßmus bigtime_t ru_time; 69*bef1ed93SStephan Aßmus uint32 wl_count; 70*bef1ed93SStephan Aßmus bigtime_t wl_time; 71*bef1ed93SStephan Aßmus uint32 wu_count; 72*bef1ed93SStephan Aßmus bigtime_t wu_time; 73*bef1ed93SStephan Aßmus uint32 islock_count; 74*bef1ed93SStephan Aßmus bigtime_t islock_time; 75*bef1ed93SStephan Aßmus uint32 reg_count; 76*bef1ed93SStephan Aßmus bigtime_t reg_time; 77*bef1ed93SStephan Aßmus uint32 unreg_count; 78*bef1ed93SStephan Aßmus bigtime_t unreg_time; 79*bef1ed93SStephan Aßmus #endif 80*bef1ed93SStephan Aßmus }; 81*bef1ed93SStephan Aßmus 82*bef1ed93SStephan Aßmus class AutoWriteLocker { 83*bef1ed93SStephan Aßmus public: AutoWriteLocker(MultiLocker * lock)84*bef1ed93SStephan Aßmus AutoWriteLocker(MultiLocker* lock) 85*bef1ed93SStephan Aßmus : fLock(lock) 86*bef1ed93SStephan Aßmus { 87*bef1ed93SStephan Aßmus fLock->WriteLock(); 88*bef1ed93SStephan Aßmus } ~AutoWriteLocker()89*bef1ed93SStephan Aßmus ~AutoWriteLocker() 90*bef1ed93SStephan Aßmus { 91*bef1ed93SStephan Aßmus fLock->WriteUnlock(); 92*bef1ed93SStephan Aßmus } 93*bef1ed93SStephan Aßmus private: 94*bef1ed93SStephan Aßmus MultiLocker* fLock; 95*bef1ed93SStephan Aßmus }; 96*bef1ed93SStephan Aßmus 97*bef1ed93SStephan Aßmus class AutoReadLocker { 98*bef1ed93SStephan Aßmus public: AutoReadLocker(MultiLocker * lock)99*bef1ed93SStephan Aßmus AutoReadLocker(MultiLocker* lock) 100*bef1ed93SStephan Aßmus : fLock(lock) 101*bef1ed93SStephan Aßmus { 102*bef1ed93SStephan Aßmus fLock->ReadLock(); 103*bef1ed93SStephan Aßmus } ~AutoReadLocker()104*bef1ed93SStephan Aßmus ~AutoReadLocker() 105*bef1ed93SStephan Aßmus { 106*bef1ed93SStephan Aßmus fLock->ReadUnlock(); 107*bef1ed93SStephan Aßmus } 108*bef1ed93SStephan Aßmus private: 109*bef1ed93SStephan Aßmus MultiLocker* fLock; 110*bef1ed93SStephan Aßmus }; 111*bef1ed93SStephan Aßmus 112*bef1ed93SStephan Aßmus 113*bef1ed93SStephan Aßmus 114*bef1ed93SStephan Aßmus #endif 115