kernel: Add read write spinlock implementation
This commit is contained in:
@@ -103,6 +103,65 @@ release_spinlock_inline(spinlock* lock)
|
||||
#endif // !DEBUG_SPINLOCKS && !B_DEBUG_SPINLOCK_CONTENTION
|
||||
|
||||
|
||||
static inline bool
|
||||
try_acquire_write_spinlock_inline(rw_spinlock* lock)
|
||||
{
|
||||
return atomic_test_and_set(&lock->lock, 1 << 31, 0) == 0;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
acquire_write_spinlock_inline(rw_spinlock* lock)
|
||||
{
|
||||
if (try_acquire_write_spinlock(lock))
|
||||
return;
|
||||
acquire_write_spinlock(lock);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
release_write_spinlock_inline(rw_spinlock* lock)
|
||||
{
|
||||
atomic_set(&lock->lock, 0);
|
||||
}
|
||||
|
||||
|
||||
static inline bool
|
||||
try_acquire_read_spinlock_inline(rw_spinlock* lock)
|
||||
{
|
||||
uint32 previous = atomic_add(&lock->lock, 1);
|
||||
if ((previous & (1 << 31)) == 0)
|
||||
return true;
|
||||
atomic_test_and_set(&lock->lock, 1 << 31, previous);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
acquire_read_spinlock_inline(rw_spinlock* lock)
|
||||
{
|
||||
if (try_acquire_read_spinlock(lock))
|
||||
return;
|
||||
acquire_read_spinlock(lock);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
release_read_spinlock_inline(rw_spinlock* lock)
|
||||
{
|
||||
atomic_add(&lock->lock, -1);
|
||||
}
|
||||
|
||||
|
||||
#define try_acquire_read_spinlock(lock) try_acquire_read_spinlock_inline(lock)
|
||||
#define acquire_read_spinlock(lock) acquire_read_spinlock_inline(lock)
|
||||
#define release_read_spinlock(lock) release_read_spinlock_inline(lock)
|
||||
#define try_acquire_write_spinlock(lock) \
|
||||
try_acquire_write_spinlock(lock)
|
||||
#define acquire_write_spinlock(lock) acquire_write_spinlock_inline(lock)
|
||||
#define release_write_spinlock(lock) release_write_spinlock_inline(lock)
|
||||
|
||||
|
||||
static inline bool
|
||||
try_acquire_write_seqlock_inline(seqlock* lock) {
|
||||
bool succeed = try_acquire_spinlock(&lock->lock);
|
||||
|
||||
@@ -160,6 +160,98 @@ private:
|
||||
typedef AutoLocker<spinlock, InterruptsSpinLocking> InterruptsSpinLocker;
|
||||
|
||||
|
||||
class ReadSpinLocking {
|
||||
public:
|
||||
inline bool Lock(rw_spinlock* lockable)
|
||||
{
|
||||
acquire_read_spinlock(lockable);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void Unlock(rw_spinlock* lockable)
|
||||
{
|
||||
release_read_spinlock(lockable);
|
||||
}
|
||||
};
|
||||
|
||||
typedef AutoLocker<rw_spinlock, ReadSpinLocking> ReadSpinLocker;
|
||||
|
||||
|
||||
class InterruptsReadSpinLocking {
|
||||
public:
|
||||
InterruptsReadSpinLocking()
|
||||
:
|
||||
fState(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline bool Lock(rw_spinlock* lockable)
|
||||
{
|
||||
fState = disable_interrupts();
|
||||
acquire_read_spinlock(lockable);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void Unlock(rw_spinlock* lockable)
|
||||
{
|
||||
release_read_spinlock(lockable);
|
||||
restore_interrupts(fState);
|
||||
}
|
||||
|
||||
private:
|
||||
int fState;
|
||||
};
|
||||
|
||||
typedef AutoLocker<rw_spinlock, InterruptsReadSpinLocking>
|
||||
InterruptsReadSpinLocker;
|
||||
|
||||
|
||||
class WriteSpinLocking {
|
||||
public:
|
||||
inline bool Lock(rw_spinlock* lockable)
|
||||
{
|
||||
acquire_write_spinlock(lockable);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void Unlock(rw_spinlock* lockable)
|
||||
{
|
||||
release_write_spinlock(lockable);
|
||||
}
|
||||
};
|
||||
|
||||
typedef AutoLocker<rw_spinlock, WriteSpinLocking> WriteSpinLocker;
|
||||
|
||||
|
||||
class InterruptsWriteSpinLocking {
|
||||
public:
|
||||
InterruptsWriteSpinLocking()
|
||||
:
|
||||
fState(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline bool Lock(rw_spinlock* lockable)
|
||||
{
|
||||
fState = disable_interrupts();
|
||||
acquire_write_spinlock(lockable);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void Unlock(rw_spinlock* lockable)
|
||||
{
|
||||
release_write_spinlock(lockable);
|
||||
restore_interrupts(fState);
|
||||
}
|
||||
|
||||
private:
|
||||
int fState;
|
||||
};
|
||||
|
||||
typedef AutoLocker<rw_spinlock, InterruptsWriteSpinLocking>
|
||||
InterruptsWriteSpinLocker;
|
||||
|
||||
|
||||
class WriteSequentialLocking {
|
||||
public:
|
||||
inline bool Lock(seqlock* lockable)
|
||||
@@ -237,6 +329,10 @@ using BPrivate::WriteLocker;
|
||||
using BPrivate::InterruptsLocker;
|
||||
using BPrivate::SpinLocker;
|
||||
using BPrivate::InterruptsSpinLocker;
|
||||
using BPrivate::ReadSpinLocker;
|
||||
using BPrivate::InterruptsReadSpinLocker;
|
||||
using BPrivate::WriteSpinLocker;
|
||||
using BPrivate::InterruptsWriteSpinLocker;
|
||||
using BPrivate::WriteSequentialLocker;
|
||||
using BPrivate::InterruptsWriteSequentialLocker;
|
||||
using BPrivate::ThreadCPUPinner;
|
||||
|
||||
Reference in New Issue
Block a user