Author: colin Date: 2009-11-30 23:27:02 +0100 (Mon, 30 Nov 2009) New Revision: 34395 Changeset: http://dev.haiku-os.org/changeset/34395/haiku Removed: haiku/trunk/src/libs/compat/freebsd_network/compat/sys/sleepqueue.h haiku/trunk/src/libs/compat/freebsd_network/sleepqueue.c Modified: haiku/trunk/src/libs/compat/freebsd_network/Condvar.cpp haiku/trunk/src/libs/compat/freebsd_network/Jamfile haiku/trunk/src/libs/compat/freebsd_network/compat/sys/condvar.h haiku/trunk/src/libs/compat/freebsd_network/condvar.h haiku/trunk/src/libs/compat/freebsd_network/synch.c Log: * Completing the condition variable subsystem. Thanks to ingo for the heads up. * Removed the cv_waiters structure member as it is nowhere used in the network subsytem by FreeBSD either. * Removing the sleepqueue dummy functions completely, as Haiku's condition variable subsystem is well suited for this purpose. * This fixes the build, too, as it introduces the new implementation of pause and _pause. * Implementing the msleep and wakeup functions based on the condition variable implementation. Modified: haiku/trunk/src/libs/compat/freebsd_network/Condvar.cpp =================================================================== --- haiku/trunk/src/libs/compat/freebsd_network/Condvar.cpp 2009-11-30 22:07:16 UTC (rev 34394) +++ haiku/trunk/src/libs/compat/freebsd_network/Condvar.cpp 2009-11-30 22:27:02 UTC (rev 34395) @@ -20,7 +20,7 @@ #include "device.h" -#define ticks_to_usecs(t) (1000000*(t) / hz) +#define ticks_to_usecs(t) (1000000*((bigtime_t)t) / hz) static const int kConditionVariableHashSize = 32; @@ -57,10 +57,14 @@ uninit_condition_variables() { InterruptsSpinLocker _(sConditionVariablesLock); - ConditionVariableHash::Iterator it = sConditionVariableHash.GetIterator(); - while (ConditionVariable* variable = it.Next()) { + ConditionVariableHashDefinition definition; + ConditionVariable* variable = sConditionVariableHash.Clear(true); + + while (variable != NULL) { + ConditionVariable* next = definition.GetLink(variable); variable->Unpublish(); - free(variable); + delete variable; + variable = next; } } @@ -68,38 +72,49 @@ void -_cv_init(struct cv* conditionVariablePointer, const char* description) +_cv_init(const void* object, const char* description) { ConditionVariable* conditionVariable = new(std::nothrow) ConditionVariable(); if (conditionVariable == NULL) panic("No memory left."); - conditionVariablePointer->cv_waiters = 0; - conditionVariable->Init(conditionVariablePointer, description); + InterruptsSpinLocker _(sConditionVariablesLock); + conditionVariable->Publish(object, description); sConditionVariableHash.Insert(conditionVariable); } void -_cv_wait_unlocked(struct cv* conditionVariablePointer) +_cv_destroy(const void* object) { InterruptsSpinLocker _(sConditionVariablesLock); - ConditionVariable* conditionVariable - = sConditionVariableHash.Lookup(conditionVariablePointer); - conditionVariablePointer->cv_waiters++; - conditionVariable->Wait(); + ConditionVariable* conditionVariable + = sConditionVariableHash.Lookup(object); + if (conditionVariable == NULL) + return; + + conditionVariable->Unpublish(); + sConditionVariableHash.RemoveUnchecked(conditionVariable); + delete conditionVariable; } +void +_cv_wait_unlocked(const void* object) +{ + ConditionVariableEntry conditionVariableEntry; + + conditionVariableEntry.Wait(object); +} + + int -_cv_timedwait_unlocked(struct cv* conditionVariablePointer, int timeout) +_cv_timedwait_unlocked(const void* object, int timeout) { - InterruptsSpinLocker _(sConditionVariablesLock); - ConditionVariable* conditionVariable - = sConditionVariableHash.Lookup(conditionVariablePointer); - conditionVariablePointer->cv_waiters++; - status_t status = conditionVariable->Wait(B_ABSOLUTE_TIMEOUT, + ConditionVariableEntry conditionVariableEntry; + + status_t status = conditionVariableEntry.Wait(object, B_ABSOLUTE_TIMEOUT, ticks_to_usecs(timeout)); if (status == B_OK) @@ -110,12 +125,26 @@ void -_cv_signal(struct cv* conditionVariablePointer) +_cv_signal(const void* object) { InterruptsSpinLocker _(sConditionVariablesLock); ConditionVariable* conditionVariable - = sConditionVariableHash.Lookup(conditionVariablePointer); - if (conditionVariablePointer->cv_waiters > 0) - conditionVariablePointer->cv_waiters--; + = sConditionVariableHash.Lookup(object); + if (conditionVariable == NULL) + return; + conditionVariable->NotifyOne(); } + + +void +_cv_broadcast(const void* object) +{ + InterruptsSpinLocker _(sConditionVariablesLock); + ConditionVariable* conditionVariable + = sConditionVariableHash.Lookup(object); + if (conditionVariable == NULL) + return; + + conditionVariable->NotifyAll(); +} Modified: haiku/trunk/src/libs/compat/freebsd_network/Jamfile =================================================================== --- haiku/trunk/src/libs/compat/freebsd_network/Jamfile 2009-11-30 22:07:16 UTC (rev 34394) +++ haiku/trunk/src/libs/compat/freebsd_network/Jamfile 2009-11-30 22:27:02 UTC (rev 34395) @@ -33,7 +33,6 @@ mii.c mutex.c priv.c - sleepqueue.c synch.c taskqueue.c timeout.c Modified: haiku/trunk/src/libs/compat/freebsd_network/compat/sys/condvar.h =================================================================== --- haiku/trunk/src/libs/compat/freebsd_network/compat/sys/condvar.h 2009-11-30 22:07:16 UTC (rev 34394) +++ haiku/trunk/src/libs/compat/freebsd_network/compat/sys/condvar.h 2009-11-30 22:27:02 UTC (rev 34395) @@ -10,7 +10,7 @@ struct cv { - int cv_waiters; + int dummy; }; Modified: haiku/trunk/src/libs/compat/freebsd_network/condvar.h =================================================================== --- haiku/trunk/src/libs/compat/freebsd_network/condvar.h 2009-11-30 22:07:16 UTC (rev 34394) +++ haiku/trunk/src/libs/compat/freebsd_network/condvar.h 2009-11-30 22:27:02 UTC (rev 34395) @@ -10,10 +10,12 @@ extern "C" { #endif -void _cv_init(struct cv*, const char*); -void _cv_wait_unlocked(struct cv *); -int _cv_timedwait_unlocked(struct cv*, int); -void _cv_signal(struct cv*); +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*); #ifdef __cplusplus } Modified: haiku/trunk/src/libs/compat/freebsd_network/synch.c =================================================================== --- haiku/trunk/src/libs/compat/freebsd_network/synch.c 2009-11-30 22:07:16 UTC (rev 34394) +++ haiku/trunk/src/libs/compat/freebsd_network/synch.c 2009-11-30 22:27:02 UTC (rev 34395) @@ -6,31 +6,27 @@ #include <compat/sys/systm.h> #include <compat/sys/kernel.h> -#include <compat/sys/sleepqueue.h> +#include <compat/sys/mutex.h> +#include "condvar.h" -#define ticks_to_msecs(t) (1000 * (t) / hz) +static int sPauseWaitChannel; + int msleep(void* identifier, struct mtx* mutex, int priority, const char* description, int timeout) { int status; - // TODO can be removed once the sleepq functions are implemented. - status = snooze(ticks_to_msecs(timeout)); - - sleepq_lock(identifier); - sleepq_add(identifier, mutex, description, 0, 0); - sleepq_release(identifier); - - status = sleepq_timedwait(identifier, timeout); - - sleepq_lock(identifier); - sleepq_remove(NULL, identifier); - sleepq_release(identifier); - + _cv_init(identifier, description); + + mtx_unlock(mutex); + status = _cv_timedwait_unlocked(identifier, timeout); + mtx_lock(mutex); + + _cv_destroy(identifier); return status; } @@ -38,7 +34,14 @@ void wakeup(void* identifier) { - sleepq_lock(identifier); - sleepq_broadcast(identifier, 0, 0, 0); - sleepq_release(identifier); + _cv_broadcast(identifier); } + + +int +_pause(const char* waitMessage, int timeout) +{ + + KASSERT(timeout != 0, ("pause: timeout required")); + return tsleep(&sPauseWaitChannel, 0, waitMessage, timeout); +}