2005-06-24 03:46:17 +04:00
|
|
|
/* MultiLocker.h */
|
|
|
|
/*
|
2006-04-07 23:14:25 +04:00
|
|
|
Copyright 2005-2006, Haiku.
|
|
|
|
Distributed under the terms of the MIT license.
|
|
|
|
|
2005-06-24 03:46:17 +04:00
|
|
|
Copyright 1999, Be Incorporated. All Rights Reserved.
|
|
|
|
This file may be used under the terms of the Be Sample Code License.
|
|
|
|
*/
|
|
|
|
|
2006-04-07 23:14:25 +04:00
|
|
|
/** multiple-reader single-writer locking class */
|
|
|
|
|
|
|
|
// IMPORTANT:
|
|
|
|
// * nested read locks are not supported
|
|
|
|
// * a reader becomming the write is not supported
|
|
|
|
// * nested write locks are supported
|
|
|
|
// * a writer can do read locks, even nested ones
|
|
|
|
// * in case of problems, #define DEBUG 1 in the .cpp
|
2005-06-24 03:46:17 +04:00
|
|
|
|
|
|
|
#ifndef MULTI_LOCKER_H
|
|
|
|
#define MULTI_LOCKER_H
|
|
|
|
|
|
|
|
//#define TIMING 1
|
|
|
|
|
|
|
|
#include <OS.h>
|
|
|
|
|
|
|
|
const int32 LARGE_NUMBER = 100000;
|
|
|
|
|
|
|
|
class MultiLocker {
|
|
|
|
public:
|
|
|
|
MultiLocker(const char* semaphoreBaseName);
|
|
|
|
virtual ~MultiLocker();
|
|
|
|
|
|
|
|
status_t InitCheck();
|
|
|
|
|
|
|
|
//locking for reading or writing
|
|
|
|
bool ReadLock();
|
|
|
|
bool WriteLock();
|
|
|
|
|
|
|
|
//unlocking after reading or writing
|
|
|
|
bool ReadUnlock();
|
|
|
|
bool WriteUnlock();
|
|
|
|
|
|
|
|
//does the current thread hold a write lock ?
|
2006-04-07 23:14:25 +04:00
|
|
|
bool IsWriteLocked(uint32 *stack_base = NULL,
|
|
|
|
thread_id *thread = NULL);
|
2005-06-24 03:46:17 +04:00
|
|
|
//in DEBUG mode returns whether the lock is held
|
|
|
|
//in non-debug mode returns true
|
|
|
|
bool IsReadLocked();
|
|
|
|
|
|
|
|
private:
|
|
|
|
//functions for managing the DEBUG reader array
|
|
|
|
void register_thread();
|
|
|
|
void unregister_thread();
|
|
|
|
|
|
|
|
status_t fInit;
|
|
|
|
//readers adjust count and block on fReadSem when a writer
|
|
|
|
//hold the lock
|
|
|
|
int32 fReadCount;
|
|
|
|
sem_id fReadSem;
|
|
|
|
//writers adjust the count and block on fWriteSem
|
|
|
|
//when readers hold the lock
|
|
|
|
int32 fWriteCount;
|
|
|
|
sem_id fWriteSem;
|
|
|
|
//writers must acquire fWriterLock when acquiring a write lock
|
|
|
|
int32 fLockCount;
|
|
|
|
sem_id fWriterLock;
|
|
|
|
int32 fWriterNest;
|
|
|
|
|
|
|
|
thread_id fWriterThread;
|
|
|
|
uint32 fWriterStackBase;
|
|
|
|
|
|
|
|
int32 * fDebugArray;
|
|
|
|
int32 fMaxThreads;
|
|
|
|
|
|
|
|
#if TIMING
|
|
|
|
uint32 rl_count;
|
|
|
|
bigtime_t rl_time;
|
|
|
|
uint32 ru_count;
|
|
|
|
bigtime_t ru_time;
|
|
|
|
uint32 wl_count;
|
|
|
|
bigtime_t wl_time;
|
|
|
|
uint32 wu_count;
|
|
|
|
bigtime_t wu_time;
|
|
|
|
uint32 islock_count;
|
|
|
|
bigtime_t islock_time;
|
|
|
|
uint32 reg_count;
|
|
|
|
bigtime_t reg_time;
|
|
|
|
uint32 unreg_count;
|
|
|
|
bigtime_t unreg_time;
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
|
|
|
class AutoWriteLocker {
|
|
|
|
public:
|
|
|
|
AutoWriteLocker(MultiLocker* lock)
|
2006-04-07 23:14:25 +04:00
|
|
|
: fLock(*lock)
|
|
|
|
{
|
|
|
|
fLock.WriteLock();
|
|
|
|
}
|
|
|
|
AutoWriteLocker(MultiLocker& lock)
|
2005-06-24 03:46:17 +04:00
|
|
|
: fLock(lock)
|
|
|
|
{
|
2006-04-07 23:14:25 +04:00
|
|
|
fLock.WriteLock();
|
2005-06-24 03:46:17 +04:00
|
|
|
}
|
|
|
|
~AutoWriteLocker()
|
|
|
|
{
|
2006-04-07 23:14:25 +04:00
|
|
|
fLock.WriteUnlock();
|
2005-06-24 03:46:17 +04:00
|
|
|
}
|
|
|
|
private:
|
2006-04-07 23:14:25 +04:00
|
|
|
MultiLocker& fLock;
|
2005-06-24 03:46:17 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
class AutoReadLocker {
|
|
|
|
public:
|
|
|
|
AutoReadLocker(MultiLocker* lock)
|
2006-04-07 23:14:25 +04:00
|
|
|
: fLock(*lock)
|
|
|
|
{
|
|
|
|
fLock.ReadLock();
|
|
|
|
}
|
|
|
|
AutoReadLocker(MultiLocker& lock)
|
2005-06-24 03:46:17 +04:00
|
|
|
: fLock(lock)
|
|
|
|
{
|
2006-04-07 23:14:25 +04:00
|
|
|
fLock.ReadLock();
|
2005-06-24 03:46:17 +04:00
|
|
|
}
|
|
|
|
~AutoReadLocker()
|
|
|
|
{
|
2006-04-07 23:14:25 +04:00
|
|
|
fLock.ReadUnlock();
|
2005-06-24 03:46:17 +04:00
|
|
|
}
|
|
|
|
private:
|
2006-04-07 23:14:25 +04:00
|
|
|
MultiLocker& fLock;
|
2005-06-24 03:46:17 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|