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
16const int32 LARGE_NUMBER = 100000;
17
18class 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
82class AutoWriteLocker {
83 public:
84								AutoWriteLocker(MultiLocker* lock)
85									: fLock(lock)
86								{
87									fLock->WriteLock();
88								}
89								~AutoWriteLocker()
90								{
91									fLock->WriteUnlock();
92								}
93 private:
94	 	MultiLocker*			fLock;
95};
96
97class AutoReadLocker {
98 public:
99								AutoReadLocker(MultiLocker* lock)
100									: fLock(lock)
101								{
102									fLock->ReadLock();
103								}
104								~AutoReadLocker()
105								{
106									fLock->ReadUnlock();
107								}
108 private:
109	 	MultiLocker*			fLock;
110};
111
112
113
114#endif
115