xref: /haiku/src/tests/servers/app/newerClipping/MultiLocker.h (revision bef1ed93e146a1bed4156b62f743e8c9cf83485c)
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