Author: colin Date: 2009-12-03 13:50:14 +0100 (Thu, 03 Dec 2009) New Revision: 34461 Changeset: http://dev.haiku-os.org/changeset/34461/haiku Ticket: http://dev.haiku-os.org/ticket/5072 Modified: haiku/trunk/src/libs/compat/freebsd_network/Condvar.cpp haiku/trunk/src/libs/compat/freebsd_network/compat/sys/condvar.h haiku/trunk/src/libs/compat/freebsd_network/condvar.c haiku/trunk/src/libs/compat/freebsd_network/condvar.h haiku/trunk/src/libs/compat/freebsd_network/synch.c Log: * 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. Modified: haiku/trunk/src/libs/compat/freebsd_network/Condvar.cpp =================================================================== --- haiku/trunk/src/libs/compat/freebsd_network/Condvar.cpp 2009-12-03 12:47:29 UTC (rev 34460) +++ haiku/trunk/src/libs/compat/freebsd_network/Condvar.cpp 2009-12-03 12:50:14 UTC (rev 34461) @@ -4,8 +4,6 @@ */ -#include "condvar.h" - extern "C" { #include <compat/sys/condvar.h> #include <compat/sys/kernel.h> @@ -14,125 +12,76 @@ #include <new> #include <condition_variable.h> -#include <util/AutoLock.h> +#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<ConditionVariableHashDefinition> 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; + variable->condition->Unpublish(); + delete variable->condition; } -void -_cv_wait_unlocked(const void* object) +int +conditionTimedWait(const struct cv* variable, const int timeout) { - ConditionVariableEntry conditionVariableEntry; + ConditionVariableEntry variableEntry; - conditionVariableEntry.Wait(object); + status_t status = variableEntry.Wait(variable->waitChannel, + B_RELATIVE_TIMEOUT, ticks_to_usecs(timeout)); + + if (status != B_OK) + status = EWOULDBLOCK; + return status; } -int -_cv_timedwait_unlocked(const void* object, int timeout) +void +conditionWait(const struct cv* variable) { - 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; + variableEntry.Wait(variable->waitChannel); } void -_cv_signal(const void* object) +conditionNotifyOne(const void* waitChannel) { - InterruptsSpinLocker _(sConditionVariablesLock); - ConditionVariable* conditionVariable - = sConditionVariableHash.Lookup(object); - if (conditionVariable == NULL) - return; - - conditionVariable->NotifyOne(); + ConditionVariable::NotifyOne(waitChannel); } void -_cv_broadcast(const void* object) +conditionNotifyAll(const void* waitChannel) { - InterruptsSpinLocker _(sConditionVariablesLock); - ConditionVariable* conditionVariable - = sConditionVariableHash.Lookup(object); - if (conditionVariable == NULL) - return; - - conditionVariable->NotifyAll(); + ConditionVariable::NotifyAll(waitChannel); } Modified: haiku/trunk/src/libs/compat/freebsd_network/compat/sys/condvar.h =================================================================== --- haiku/trunk/src/libs/compat/freebsd_network/compat/sys/condvar.h 2009-12-03 12:47:29 UTC (rev 34460) +++ haiku/trunk/src/libs/compat/freebsd_network/compat/sys/condvar.h 2009-12-03 12:50:14 UTC (rev 34461) @@ -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*); Modified: haiku/trunk/src/libs/compat/freebsd_network/condvar.c =================================================================== --- haiku/trunk/src/libs/compat/freebsd_network/condvar.c 2009-12-03 12:47:29 UTC (rev 34460) +++ haiku/trunk/src/libs/compat/freebsd_network/condvar.c 2009-12-03 12:50:14 UTC (rev 34461) @@ -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) { - int status; + conditionNotifyOne(variable); +} - _cv_init(conditionVariable, conditionVariable->description); +int cv_timedwait(struct cv* variable, struct mtx* mutex, int timeout) +{ + int status; + 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); } Modified: haiku/trunk/src/libs/compat/freebsd_network/condvar.h =================================================================== --- haiku/trunk/src/libs/compat/freebsd_network/condvar.h 2009-12-03 12:47:29 UTC (rev 34460) +++ haiku/trunk/src/libs/compat/freebsd_network/condvar.h 2009-12-03 12:50:14 UTC (rev 34461) @@ -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 } Modified: haiku/trunk/src/libs/compat/freebsd_network/synch.c =================================================================== --- haiku/trunk/src/libs/compat/freebsd_network/synch.c 2009-12-03 12:47:29 UTC (rev 34460) +++ haiku/trunk/src/libs/compat/freebsd_network/synch.c 2009-12-03 12:50:14 UTC (rev 34461) @@ -7,26 +7,26 @@ #include <compat/sys/systm.h> #include <compat/sys/kernel.h> #include <compat/sys/mutex.h> +#include <compat/sys/condvar.h> #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; - _cv_init(identifier, description); - + conditionPublish(&sleep, 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 @@ 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); }