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