haiku/headers/private/kernel/util/AutoLock.h
Ingo Weinhold 8562499f44 * Introduced a new locking primitive I called "cutex" (sorry for the
name, couldn't resist :-P). It's semantically equivalent to a mutex,
  but doesn't need a semaphore (it uses thread blocking and a simple
  queue instead). Initialization can't fail. In fact it is ready to use
  without initialization when living in the bss segment, also in the
  early boot process. It's as fast as a benaphore in cases of low lock
  contention, and faster otherwise.  Only disadvantage is the higher
  immediate memory footprint of 16 bytes.
* Changed how the "thread" and "threads" debugger commands list the
  objects they are waiting for. Cutexes are also included.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25276 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-05-01 01:53:07 +00:00

180 lines
3.1 KiB
C++

/*
* Copyright 2005-2007, Ingo Weinhold, bonefish@users.sf.net. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef KERNEL_UTIL_AUTO_LOCKER_H
#define KERNEL_UTIL_AUTO_LOCKER_H
#include <KernelExport.h>
#include <shared/AutoLocker.h>
#include <int.h>
#include <lock.h>
namespace BPrivate {
// MutexLocking
class MutexLocking {
public:
inline bool Lock(mutex *lockable)
{
return mutex_lock(lockable) == B_OK;
}
inline void Unlock(mutex *lockable)
{
mutex_unlock(lockable);
}
};
// MutexLocker
typedef AutoLocker<mutex, MutexLocking> MutexLocker;
// RecursiveLockLocking
class RecursiveLockLocking {
public:
inline bool Lock(recursive_lock *lockable)
{
return recursive_lock_lock(lockable) == B_OK;
}
inline void Unlock(recursive_lock *lockable)
{
recursive_lock_unlock(lockable);
}
};
// RecursiveLocker
typedef AutoLocker<recursive_lock, RecursiveLockLocking> RecursiveLocker;
// BenaphoreLocking
class BenaphoreLocking {
public:
inline bool Lock(benaphore *lockable)
{
return benaphore_lock(lockable) == B_OK;
}
inline void Unlock(benaphore *lockable)
{
benaphore_unlock(lockable);
}
};
// BenaphoreLocker
typedef AutoLocker<benaphore, BenaphoreLocking> BenaphoreLocker;
// CutexLocking
class CutexLocking {
public:
inline bool Lock(cutex *lockable)
{
cutex_lock(lockable);
return true;
}
inline void Unlock(cutex *lockable)
{
cutex_unlock(lockable);
}
};
// CutexLocker
typedef AutoLocker<cutex, CutexLocking> CutexLocker;
// InterruptsLocking
class InterruptsLocking {
public:
inline bool Lock(int* lockable)
{
*lockable = disable_interrupts();
return true;
}
inline void Unlock(int* lockable)
{
restore_interrupts(*lockable);
}
};
// InterruptsLocker
class InterruptsLocker : public AutoLocker<int, InterruptsLocking> {
public:
inline InterruptsLocker(bool alreadyLocked = false,
bool lockIfNotLocked = true)
: AutoLocker<int, InterruptsLocking>(&fState, alreadyLocked,
lockIfNotLocked)
{
}
private:
int fState;
};
// SpinLocking
class SpinLocking {
public:
inline bool Lock(spinlock* lockable)
{
acquire_spinlock(lockable);
return true;
}
inline void Unlock(spinlock* lockable)
{
release_spinlock(lockable);
}
};
// SpinLocker
typedef AutoLocker<spinlock, SpinLocking> SpinLocker;
// InterruptsSpinLocking
class InterruptsSpinLocking {
public:
struct State {
State(spinlock* lock)
: lock(lock)
{
}
int state;
spinlock* lock;
};
inline bool Lock(spinlock* lockable)
{
fState = disable_interrupts();
acquire_spinlock(lockable);
return true;
}
inline void Unlock(spinlock* lockable)
{
release_spinlock(lockable);
restore_interrupts(fState);
}
private:
int fState;
};
// InterruptsSpinLocker
typedef AutoLocker<spinlock, InterruptsSpinLocking> InterruptsSpinLocker;
} // namespace BPrivate
using BPrivate::AutoLocker;
using BPrivate::MutexLocker;
using BPrivate::RecursiveLocker;
using BPrivate::BenaphoreLocker;
using BPrivate::CutexLocker;
using BPrivate::InterruptsLocker;
using BPrivate::SpinLocker;
using BPrivate::InterruptsSpinLocker;
#endif // KERNEL_UTIL_AUTO_LOCKER_H