From a49ed9ad76c88ad2eb250fae1482750c2a32281b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Colin=20G=C3=BCnther?= Date: Thu, 3 Dec 2009 12:50:14 +0000 Subject: [PATCH] * Refactoring the condition variable and synchronization subsystem of the freebsd compat layer. * Renaming functions where their names aren't preset by FreeBSD to stick to the coding style guidelines. * Making use of static Notify functions of Haiku's ConditionalVariable implementation. * Removing management of used ConditionalVariables within the compat layer. This should also fix #5072. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34461 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/libs/compat/freebsd_network/Condvar.cpp | 113 +++++------------- .../freebsd_network/compat/sys/condvar.h | 3 + src/libs/compat/freebsd_network/condvar.c | 30 +++-- src/libs/compat/freebsd_network/condvar.h | 12 +- src/libs/compat/freebsd_network/synch.c | 22 ++-- 5 files changed, 65 insertions(+), 115 deletions(-) diff --git a/src/libs/compat/freebsd_network/Condvar.cpp b/src/libs/compat/freebsd_network/Condvar.cpp index a18c99301f..968fc73ba5 100644 --- a/src/libs/compat/freebsd_network/Condvar.cpp +++ b/src/libs/compat/freebsd_network/Condvar.cpp @@ -4,8 +4,6 @@ */ -#include "condvar.h" - extern "C" { #include #include @@ -14,125 +12,76 @@ extern "C" { #include #include -#include +#include "condvar.h" #include "device.h" #define ticks_to_usecs(t) (1000000*((bigtime_t)t) / hz) -static const int kConditionVariableHashSize = 32; - - -struct ConditionVariableHashDefinition { - typedef const void* KeyType; - typedef ConditionVariable ValueType; - - size_t HashKey(const void* key) const - { return (size_t)key; } - size_t Hash(ConditionVariable* variable) const - { return (size_t)variable->fObject; } - bool Compare(const void* key, ConditionVariable* variable) const - { return key == variable->fObject; } - ConditionVariable*& GetLink(ConditionVariable* variable) const - { return variable->fNext; } -}; - -typedef BOpenHashTable ConditionVariableHash; -static ConditionVariableHash sConditionVariableHash; -static spinlock sConditionVariablesLock; - -extern "C" { - status_t init_condition_variables() { - return sConditionVariableHash.Init(kConditionVariableHashSize); + return B_OK; } void uninit_condition_variables() {} -} /* extern "C" */ - void -_cv_init(const void* object, const char* description) +conditionPublish(struct cv* variable, const void* waitChannel, + const char* description) { - ConditionVariable* conditionVariable - = new(std::nothrow) ConditionVariable(); - if (conditionVariable == NULL) - panic("No memory left."); - - InterruptsSpinLocker _(sConditionVariablesLock); - conditionVariable->Publish(object, description); - sConditionVariableHash.Insert(conditionVariable); + variable->waitChannel = waitChannel; + variable->description = description; + variable->condition = new(std::nothrow) ConditionVariable(); + variable->condition->Publish(waitChannel, description); } void -_cv_destroy(const void* object) +conditionUnpublish(const struct cv* variable) { - InterruptsSpinLocker hashLocker(sConditionVariablesLock); - ConditionVariable* conditionVariable - = sConditionVariableHash.Lookup(object); - hashLocker.Unlock(); - if (conditionVariable == NULL) - return; - - conditionVariable->Unpublish(); - sConditionVariableHash.RemoveUnchecked(conditionVariable); - delete conditionVariable; -} - - -void -_cv_wait_unlocked(const void* object) -{ - ConditionVariableEntry conditionVariableEntry; - - conditionVariableEntry.Wait(object); + variable->condition->Unpublish(); + delete variable->condition; } int -_cv_timedwait_unlocked(const void* object, int timeout) +conditionTimedWait(const struct cv* variable, const int timeout) { - ConditionVariableEntry conditionVariableEntry; - - status_t status = conditionVariableEntry.Wait(object, B_RELATIVE_TIMEOUT, - ticks_to_usecs(timeout)); + ConditionVariableEntry variableEntry; - if (status == B_OK) - return ENOERR; - else - return EWOULDBLOCK; + status_t status = variableEntry.Wait(variable->waitChannel, + B_RELATIVE_TIMEOUT, ticks_to_usecs(timeout)); + + if (status != B_OK) + status = EWOULDBLOCK; + return status; } void -_cv_signal(const void* object) +conditionWait(const struct cv* variable) { - InterruptsSpinLocker _(sConditionVariablesLock); - ConditionVariable* conditionVariable - = sConditionVariableHash.Lookup(object); - if (conditionVariable == NULL) - return; + ConditionVariableEntry variableEntry; - conditionVariable->NotifyOne(); + variableEntry.Wait(variable->waitChannel); } void -_cv_broadcast(const void* object) +conditionNotifyOne(const void* waitChannel) { - InterruptsSpinLocker _(sConditionVariablesLock); - ConditionVariable* conditionVariable - = sConditionVariableHash.Lookup(object); - if (conditionVariable == NULL) - return; - - conditionVariable->NotifyAll(); + ConditionVariable::NotifyOne(waitChannel); +} + + +void +conditionNotifyAll(const void* waitChannel) +{ + ConditionVariable::NotifyAll(waitChannel); } diff --git a/src/libs/compat/freebsd_network/compat/sys/condvar.h b/src/libs/compat/freebsd_network/compat/sys/condvar.h index a2ef47656e..862a8968d4 100644 --- a/src/libs/compat/freebsd_network/compat/sys/condvar.h +++ b/src/libs/compat/freebsd_network/compat/sys/condvar.h @@ -10,11 +10,14 @@ struct cv { + struct ConditionVariable* condition; const char* description; + const void* waitChannel; }; void cv_init(struct cv*, const char*); +void cv_destroy(struct cv*); void cv_wait(struct cv*, struct mtx*); int cv_timedwait(struct cv*, struct mtx*, int); void cv_signal(struct cv*); diff --git a/src/libs/compat/freebsd_network/condvar.c b/src/libs/compat/freebsd_network/condvar.c index 2251878a4e..bf5eea0f98 100644 --- a/src/libs/compat/freebsd_network/condvar.c +++ b/src/libs/compat/freebsd_network/condvar.c @@ -10,41 +10,39 @@ #include "condvar.h" -void cv_init(struct cv* conditionVariable, const char* description) +void cv_init(struct cv* variable, const char* description) { - conditionVariable->description = description; + conditionPublish(variable, variable, description); } -void cv_signal(struct cv* conditionVariable) +void cv_destroy(struct cv* variable) { - _cv_signal(conditionVariable); + conditionUnpublish(variable); } -int cv_timedwait(struct cv* conditionVariable, struct mtx* mutex, int timeout) +void cv_signal(struct cv* variable) +{ + conditionNotifyOne(variable); +} + + +int cv_timedwait(struct cv* variable, struct mtx* mutex, int timeout) { int status; - _cv_init(conditionVariable, conditionVariable->description); - mtx_unlock(mutex); - status = _cv_timedwait_unlocked(conditionVariable, timeout); + status = conditionTimedWait(variable, timeout); mtx_lock(mutex); - _cv_destroy(conditionVariable); - return status; } -void cv_wait(struct cv* conditionVariable, struct mtx* mutex) +void cv_wait(struct cv* variable, struct mtx* mutex) { - _cv_init(conditionVariable, conditionVariable->description); - mtx_unlock(mutex); - _cv_wait_unlocked(conditionVariable); + conditionWait(variable); mtx_lock(mutex); - - _cv_destroy(conditionVariable); } diff --git a/src/libs/compat/freebsd_network/condvar.h b/src/libs/compat/freebsd_network/condvar.h index fec109aa4d..2a0dba0b5c 100644 --- a/src/libs/compat/freebsd_network/condvar.h +++ b/src/libs/compat/freebsd_network/condvar.h @@ -10,12 +10,12 @@ extern "C" { #endif -void _cv_init(const void*, const char*); -void _cv_destroy(const void*); -void _cv_wait_unlocked(const void*); -int _cv_timedwait_unlocked(const void*, int); -void _cv_signal(const void*); -void _cv_broadcast(const void*); +void conditionPublish(struct cv*, const void*, const char*); +void conditionUnpublish(const struct cv*); +void conditionNotifyOne(const void*); +void conditionNotifyAll(const void*); +int conditionTimedWait(const struct cv*, const int); +void conditionWait(const struct cv*); #ifdef __cplusplus } diff --git a/src/libs/compat/freebsd_network/synch.c b/src/libs/compat/freebsd_network/synch.c index 0d5ee4a0a3..1557ff7647 100644 --- a/src/libs/compat/freebsd_network/synch.c +++ b/src/libs/compat/freebsd_network/synch.c @@ -7,26 +7,26 @@ #include #include #include +#include #include "condvar.h" -static int sPauseWaitChannel; - - int msleep(void* identifier, struct mtx* mutex, int priority, const char* description, int timeout) { int status; + struct cv sleep; + + conditionPublish(&sleep, identifier, description); - _cv_init(identifier, description); - mtx_unlock(mutex); - status = _cv_timedwait_unlocked(identifier, timeout); + status = conditionTimedWait(&sleep, timeout); mtx_lock(mutex); - - _cv_destroy(identifier); + + conditionUnpublish(&sleep); + return status; } @@ -34,14 +34,14 @@ msleep(void* identifier, struct mtx* mutex, int priority, void wakeup(void* identifier) { - _cv_broadcast(identifier); + conditionNotifyAll(identifier); } int _pause(const char* waitMessage, int timeout) { - + int waitChannel; KASSERT(timeout != 0, ("pause: timeout required")); - return tsleep(&sPauseWaitChannel, 0, waitMessage, timeout); + return tsleep(&waitChannel, 0, waitMessage, timeout); }