From 8bef23107e85569f85d0658ac3a03b87401ed566 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Sun, 29 Nov 2009 11:14:50 +0000 Subject: [PATCH] Added a lazy_recursive_lock implementation -- identical to recursive_lock, just using a lazy_mutex instead. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34341 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/shared/locks.h | 26 ++++++++++---- src/system/libroot/os/locks.cpp | 62 +++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 6 deletions(-) diff --git a/headers/private/shared/locks.h b/headers/private/shared/locks.h index 77fa0901af..f1dc37a1df 100644 --- a/headers/private/shared/locks.h +++ b/headers/private/shared/locks.h @@ -60,12 +60,26 @@ typedef struct recursive_lock { int recursion; } recursive_lock; -extern status_t recursive_lock_init(recursive_lock *lock, const char *name); -extern void recursive_lock_destroy(recursive_lock *lock); -extern status_t recursive_lock_lock(recursive_lock *lock); -extern status_t recursive_lock_trylock(recursive_lock *lock); -extern void recursive_lock_unlock(recursive_lock *lock); -extern int32 recursive_lock_get_recursion(recursive_lock *lock); +status_t recursive_lock_init(recursive_lock *lock, const char *name); +void recursive_lock_destroy(recursive_lock *lock); +status_t recursive_lock_lock(recursive_lock *lock); +void recursive_lock_unlock(recursive_lock *lock); +int32 recursive_lock_get_recursion(recursive_lock *lock); + + +typedef struct lazy_recursive_lock { + lazy_mutex lock; + thread_id holder; + int recursion; +} lazy_recursive_lock; + +status_t lazy_recursive_lock_init(lazy_recursive_lock *lock, + const char *name); + // name will not be cloned and must rename valid +void lazy_recursive_lock_destroy(lazy_recursive_lock *lock); +status_t lazy_recursive_lock_lock(lazy_recursive_lock *lock); +void lazy_recursive_lock_unlock(lazy_recursive_lock *lock); +int32 lazy_recursive_lock_get_recursion(lazy_recursive_lock *lock); #ifdef __cplusplus } // extern "C" diff --git a/src/system/libroot/os/locks.cpp b/src/system/libroot/os/locks.cpp index 1ed595ca10..1bf6d777a5 100644 --- a/src/system/libroot/os/locks.cpp +++ b/src/system/libroot/os/locks.cpp @@ -427,3 +427,65 @@ recursive_lock_unlock(recursive_lock *lock) mutex_unlock(&lock->lock); } } + + +// #pragma mark - lazy recursive lock + + +int32 +lazy_recursive_lock_get_recursion(lazy_recursive_lock *lock) +{ + if (lock->holder == find_thread(NULL)) + return lock->recursion; + + return -1; +} + + +status_t +lazy_recursive_lock_init(lazy_recursive_lock *lock, const char *name) +{ + lock->holder = -1; + lock->recursion = 0; + return lazy_mutex_init(&lock->lock, name != NULL ? name : "recursive lock"); +} + + +void +lazy_recursive_lock_destroy(lazy_recursive_lock *lock) +{ + if (lock == NULL) + return; + + lazy_mutex_destroy(&lock->lock); +} + + +status_t +lazy_recursive_lock_lock(lazy_recursive_lock *lock) +{ + thread_id thread = find_thread(NULL); + + if (thread != lock->holder) { + lazy_mutex_lock(&lock->lock); + lock->holder = thread; + } + + lock->recursion++; + return B_OK; +} + + +void +lazy_recursive_lock_unlock(lazy_recursive_lock *lock) +{ + if (find_thread(NULL) != lock->holder) { + debugger("lazy_recursive_lock unlocked by non-holder thread!\n"); + return; + } + + if (--lock->recursion == 0) { + lock->holder = -1; + lazy_mutex_unlock(&lock->lock); + } +}