From d03e5994ee9c1a80bb74ac34dba14f0b34c59106 Mon Sep 17 00:00:00 2001 From: X512 Date: Sun, 30 Jan 2022 15:49:44 +0900 Subject: [PATCH] ConditionVariable: add classical wait interface with lockable Change-Id: Id18264e786dba818138caf3908c7a89b18e2a1dd Reviewed-on: https://review.haiku-os.org/c/haiku/+/4921 Tested-by: Commit checker robot Reviewed-by: waddlesplash --- headers/private/kernel/condition_variable.h | 5 +++ src/system/kernel/condition_variable.cpp | 43 +++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/headers/private/kernel/condition_variable.h b/headers/private/kernel/condition_variable.h index 2a3d60545c..1538caf800 100644 --- a/headers/private/kernel/condition_variable.h +++ b/headers/private/kernel/condition_variable.h @@ -17,6 +17,8 @@ #include +struct mutex; +struct recursive_lock; struct ConditionVariable; @@ -72,6 +74,9 @@ public: status_t Wait(uint32 flags = 0, bigtime_t timeout = 0); // all-in one, i.e. doesn't need a // ConditionVariableEntry + status_t Wait(mutex* lock, uint32 flags = 0, bigtime_t timeout = 0); + status_t Wait(recursive_lock* lock, uint32 flags = 0, bigtime_t timeout = 0); + status_t Wait(spinlock* lock, uint32 flags = 0, bigtime_t timeout = 0); const void* Object() const { return fObject; } const char* ObjectType() const { return fObjectType; } diff --git a/src/system/kernel/condition_variable.cpp b/src/system/kernel/condition_variable.cpp index 37bf9c5536..98a4e119b0 100644 --- a/src/system/kernel/condition_variable.cpp +++ b/src/system/kernel/condition_variable.cpp @@ -333,6 +333,49 @@ ConditionVariable::Wait(uint32 flags, bigtime_t timeout) } +status_t +ConditionVariable::Wait(mutex* lock, uint32 flags, bigtime_t timeout) +{ + ConditionVariableEntry entry; + Add(&entry); + mutex_unlock(lock); + status_t res = entry.Wait(flags, timeout); + mutex_lock(lock); + return res; +} + + +status_t +ConditionVariable::Wait(recursive_lock* lock, uint32 flags, bigtime_t timeout) +{ + ConditionVariableEntry entry; + Add(&entry); + int32 recursion = recursive_lock_get_recursion(lock); + + for (int32 i = 0; i < recursion; i++) + recursive_lock_unlock(lock); + + status_t res = entry.Wait(flags, timeout); + + for (int32 i = 0; i < recursion; i++) + recursive_lock_lock(lock); + + return res; +} + + +status_t +ConditionVariable::Wait(spinlock* lock, uint32 flags, bigtime_t timeout) +{ + ConditionVariableEntry entry; + Add(&entry); + release_spinlock(lock); + status_t res = entry.Wait(flags, timeout); + acquire_spinlock(lock); + return res; +} + + /*static*/ void ConditionVariable::NotifyOne(const void* object, status_t result) {