* 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. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34395 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ KernelStaticLibrary libfreebsd_network.a :
|
||||
mii.c
|
||||
mutex.c
|
||||
priv.c
|
||||
sleepqueue.c
|
||||
synch.c
|
||||
taskqueue.c
|
||||
timeout.c
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
|
||||
struct cv {
|
||||
int cv_waiters;
|
||||
int dummy;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
/*
|
||||
* Copyright 2009, Colin Günther, [email protected]
|
||||
* 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_ */
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright 2009 Colin Günther, [email protected]
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <compat/sys/systm.h>
|
||||
#include <compat/sys/sleepqueue.h>
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -6,10 +6,12 @@
|
||||
|
||||
#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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user