diff --git a/src/libs/compat/freebsd_network/Condvar.cpp b/src/libs/compat/freebsd_network/Condvar.cpp index 6d583eb430..3673164162 100644 --- a/src/libs/compat/freebsd_network/Condvar.cpp +++ b/src/libs/compat/freebsd_network/Condvar.cpp @@ -20,7 +20,7 @@ extern "C" { #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 @@ void 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 @@ uninit_condition_variables() 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 @@ _cv_timedwait_unlocked(struct cv* conditionVariablePointer, int timeout) 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(); +} diff --git a/src/libs/compat/freebsd_network/Jamfile b/src/libs/compat/freebsd_network/Jamfile index e5e92dac2a..5933eaae41 100644 --- a/src/libs/compat/freebsd_network/Jamfile +++ b/src/libs/compat/freebsd_network/Jamfile @@ -33,7 +33,6 @@ KernelStaticLibrary libfreebsd_network.a : mii.c mutex.c priv.c - sleepqueue.c synch.c taskqueue.c timeout.c diff --git a/src/libs/compat/freebsd_network/compat/sys/condvar.h b/src/libs/compat/freebsd_network/compat/sys/condvar.h index aa9abb3f91..a646ba5bd9 100644 --- a/src/libs/compat/freebsd_network/compat/sys/condvar.h +++ b/src/libs/compat/freebsd_network/compat/sys/condvar.h @@ -10,7 +10,7 @@ struct cv { - int cv_waiters; + int dummy; }; diff --git a/src/libs/compat/freebsd_network/compat/sys/sleepqueue.h b/src/libs/compat/freebsd_network/compat/sys/sleepqueue.h deleted file mode 100644 index 58a10e2e73..0000000000 --- a/src/libs/compat/freebsd_network/compat/sys/sleepqueue.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2009, Colin Günther, coling@gmx.de - * All Rights Reserved. Distributed under the terms of the MIT License. - */ -#ifndef _FBSD_COMPAT_SYS_SLEEPQUEUE_H_ -#define _FBSD_COMPAT_SYS_SLEEPQUEUE_H_ - - -void sleepq_add(void*, struct mtx*, const char*, int, int); -int sleepq_broadcast(void*, int, int, int); -void sleepq_lock(void*); -void sleepq_release(void*); -void sleepq_remove(struct thread*, void*); -int sleepq_timedwait(void*, int); - -#endif /* _FBSD_COMPAT_SYS_SLEEPQUEUE_H_ */ diff --git a/src/libs/compat/freebsd_network/condvar.h b/src/libs/compat/freebsd_network/condvar.h index e0698474e0..fec109aa4d 100644 --- a/src/libs/compat/freebsd_network/condvar.h +++ b/src/libs/compat/freebsd_network/condvar.h @@ -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 } diff --git a/src/libs/compat/freebsd_network/sleepqueue.c b/src/libs/compat/freebsd_network/sleepqueue.c deleted file mode 100644 index e01b770869..0000000000 --- a/src/libs/compat/freebsd_network/sleepqueue.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2009 Colin Günther, coling@gmx.de - * All rights reserved. Distributed under the terms of the MIT License. - */ - - -#include -#include - - -void -sleepq_add(void* identifier, struct mtx* mutex, const char* description, - int flags, int queue) -{ - -} - - -int -sleepq_broadcast(void* identifier, int flags, int priority, int queue) -{ - return 0; -} - - -void -sleepq_lock(void* identifier) -{ - -} - - -void -sleepq_release(void* identifier) -{ - -} - - -void -sleepq_remove(struct thread* thread, void* identifier) -{ - -} - - -int -sleepq_timedwait(void* identifier, int priority) -{ - return 0; -} diff --git a/src/libs/compat/freebsd_network/synch.c b/src/libs/compat/freebsd_network/synch.c index ee88207dae..0d5ee4a0a3 100644 --- a/src/libs/compat/freebsd_network/synch.c +++ b/src/libs/compat/freebsd_network/synch.c @@ -6,10 +6,12 @@ #include #include -#include +#include + +#include "condvar.h" -#define ticks_to_msecs(t) (1000 * (t) / hz) +static int sPauseWaitChannel; int @@ -18,19 +20,13 @@ msleep(void* identifier, struct mtx* mutex, int priority, { 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 @@ msleep(void* identifier, struct mtx* mutex, int priority, 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); }