kernel: Protect lock internals with per-lock spinlock
This commit is contained in:
@@ -18,6 +18,7 @@ struct mutex_waiter;
|
||||
typedef struct mutex {
|
||||
const char* name;
|
||||
struct mutex_waiter* waiters;
|
||||
spinlock lock;
|
||||
#if KDEBUG
|
||||
thread_id holder;
|
||||
#else
|
||||
@@ -44,6 +45,7 @@ struct rw_lock_waiter;
|
||||
typedef struct rw_lock {
|
||||
const char* name;
|
||||
struct rw_lock_waiter* waiters;
|
||||
spinlock lock;
|
||||
thread_id holder;
|
||||
vint32 count;
|
||||
int32 owner_count;
|
||||
@@ -88,14 +90,17 @@ typedef struct rw_lock {
|
||||
|
||||
// static initializers
|
||||
#if KDEBUG
|
||||
# define MUTEX_INITIALIZER(name) { name, NULL, -1, 0 }
|
||||
# define MUTEX_INITIALIZER(name) \
|
||||
{ name, NULL, B_SPINLOCK_INITIALIZER, -1, 0 }
|
||||
# define RECURSIVE_LOCK_INITIALIZER(name) { MUTEX_INITIALIZER(name), 0 }
|
||||
#else
|
||||
# define MUTEX_INITIALIZER(name) { name, NULL, 0, 0, 0 }
|
||||
# define MUTEX_INITIALIZER(name) \
|
||||
{ name, NULL, B_SPINLOCK_INITIALIZER, 0, 0, 0 }
|
||||
# define RECURSIVE_LOCK_INITIALIZER(name) { MUTEX_INITIALIZER(name), -1, 0 }
|
||||
#endif
|
||||
|
||||
#define RW_LOCK_INITIALIZER(name) { name, NULL, -1, 0, 0, 0 }
|
||||
#define RW_LOCK_INITIALIZER(name) \
|
||||
{ name, NULL, B_SPINLOCK_INITIALIZER, -1, 0, 0, 0 }
|
||||
|
||||
|
||||
#if KDEBUG
|
||||
@@ -144,11 +149,11 @@ extern status_t mutex_switch_from_read_lock(rw_lock* from, mutex* to);
|
||||
extern status_t _rw_lock_read_lock(rw_lock* lock);
|
||||
extern status_t _rw_lock_read_lock_with_timeout(rw_lock* lock,
|
||||
uint32 timeoutFlags, bigtime_t timeout);
|
||||
extern void _rw_lock_read_unlock(rw_lock* lock, bool schedulerLocked);
|
||||
extern void _rw_lock_write_unlock(rw_lock* lock, bool schedulerLocked);
|
||||
extern void _rw_lock_read_unlock(rw_lock* lock);
|
||||
extern void _rw_lock_write_unlock(rw_lock* lock);
|
||||
|
||||
extern status_t _mutex_lock(mutex* lock, bool schedulerLocked);
|
||||
extern void _mutex_unlock(mutex* lock, bool schedulerLocked);
|
||||
extern status_t _mutex_lock(mutex* lock, void* locker);
|
||||
extern void _mutex_unlock(mutex* lock);
|
||||
extern status_t _mutex_trylock(mutex* lock);
|
||||
extern status_t _mutex_lock_with_timeout(mutex* lock, uint32 timeoutFlags,
|
||||
bigtime_t timeout);
|
||||
@@ -191,7 +196,7 @@ rw_lock_read_unlock(rw_lock* lock)
|
||||
#else
|
||||
int32 oldCount = atomic_add(&lock->count, -1);
|
||||
if (oldCount >= RW_LOCK_WRITER_COUNT_BASE)
|
||||
_rw_lock_read_unlock(lock, false);
|
||||
_rw_lock_read_unlock(lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -199,7 +204,7 @@ rw_lock_read_unlock(rw_lock* lock)
|
||||
static inline void
|
||||
rw_lock_write_unlock(rw_lock* lock)
|
||||
{
|
||||
_rw_lock_write_unlock(lock, false);
|
||||
_rw_lock_write_unlock(lock);
|
||||
}
|
||||
|
||||
|
||||
@@ -207,23 +212,10 @@ static inline status_t
|
||||
mutex_lock(mutex* lock)
|
||||
{
|
||||
#if KDEBUG
|
||||
return _mutex_lock(lock, false);
|
||||
return _mutex_lock(lock, NULL);
|
||||
#else
|
||||
if (atomic_add(&lock->count, -1) < 0)
|
||||
return _mutex_lock(lock, false);
|
||||
return B_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static inline status_t
|
||||
mutex_lock_threads_locked(mutex* lock)
|
||||
{
|
||||
#if KDEBUG
|
||||
return _mutex_lock(lock, true);
|
||||
#else
|
||||
if (atomic_add(&lock->count, -1) < 0)
|
||||
return _mutex_lock(lock, true);
|
||||
return _mutex_lock(lock, NULL);
|
||||
return B_OK;
|
||||
#endif
|
||||
}
|
||||
@@ -261,7 +253,7 @@ mutex_unlock(mutex* lock)
|
||||
#if !KDEBUG
|
||||
if (atomic_add(&lock->count, 1) < -1)
|
||||
#endif
|
||||
_mutex_unlock(lock, false);
|
||||
_mutex_unlock(lock);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user