diff --git a/src/libs/compat/freebsd_network/Condvar.cpp b/src/libs/compat/freebsd_network/Condvar.cpp deleted file mode 100644 index a7bbcd85a3..0000000000 --- a/src/libs/compat/freebsd_network/Condvar.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2009 Colin Günther, coling@gmx.de - * All Rights Reserved. Distributed under the terms of the MIT License. - */ - - -extern "C" { -#include -#include -} - -#include "Condvar.h" - - -void -conditionInit(struct cv* variable, const char* description) -{ - variable->condition.Init(variable, description); -} - - -void -conditionPublish(struct cv* variable, const void* waitChannel, - const char* description) -{ - variable->condition.Publish(waitChannel, description); -} - - -void -conditionUnpublish(struct cv* variable) -{ - variable->condition.Unpublish(); -} - - -int -conditionTimedWait(struct cv* variable, const int timeout) -{ - status_t status = variable->condition.Wait(B_RELATIVE_TIMEOUT, - TICKS_2_USEC(timeout)); - - if (status != B_OK) - status = EWOULDBLOCK; - return status; -} - - -void -conditionWait(struct cv* variable) -{ - variable->condition.Wait(); -} - - -void -conditionNotifyOne(struct cv* variable) -{ - variable->condition.NotifyOne(); -} - - -int -publishedConditionTimedWait(const void* waitChannel, const int timeout) -{ - ConditionVariableEntry variableEntry; - bigtime_t usecs = TICKS_2_USEC(timeout); - - // FreeBSD has a condition-variable scheduling system with different - // scheduling semantics than ours does. As a result, it seems there are - // some scenarios which work fine under FreeBSD but race into a deadlock - // on Haiku. To avoid this, turn unlimited timeouts into 1sec ones. - status_t status = variableEntry.Wait(waitChannel, B_RELATIVE_TIMEOUT, - usecs > 0 ? usecs : 1000 * 1000); - - if (status != B_OK) - status = EWOULDBLOCK; - return status; -} - - -void -publishedConditionNotifyAll(const void* waitChannel) -{ - ConditionVariable::NotifyAll(waitChannel, B_OK); -} - - -void -publishedConditionNotifyOne(const void* waitChannel) -{ - ConditionVariable::NotifyOne(waitChannel, B_OK); -} diff --git a/src/libs/compat/freebsd_network/Condvar.h b/src/libs/compat/freebsd_network/Condvar.h deleted file mode 100644 index e774fc442c..0000000000 --- a/src/libs/compat/freebsd_network/Condvar.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2009 Colin Günther, coling@gmx.de - * All Rights Reserved. Distributed under the terms of the MIT License. - */ -#ifndef CONDVAR_H_ -#define CONDVAR_H_ - - -#ifdef __cplusplus -extern "C" { -#endif - -void conditionInit(struct cv*, const char*); -void conditionPublish(struct cv*, const void*, const char*); -void conditionUnpublish(struct cv*); -int conditionTimedWait(struct cv*, const int); -void conditionWait(struct cv*); -void conditionNotifyOne(struct cv*); -int publishedConditionTimedWait(const void*, const int); -void publishedConditionNotifyAll(const void*); -void publishedConditionNotifyOne(const void*); - -#ifdef __cplusplus -} -#endif - -#endif /* CONDVAR_H_ */ diff --git a/src/libs/compat/freebsd_network/Jamfile b/src/libs/compat/freebsd_network/Jamfile index cb08869d70..432c3d3d01 100644 --- a/src/libs/compat/freebsd_network/Jamfile +++ b/src/libs/compat/freebsd_network/Jamfile @@ -18,8 +18,7 @@ KernelStaticLibrary libfreebsd_network.a : bus_dma.cpp callout.cpp clock.c - condvar.c - Condvar.cpp + condvar.cpp device.c device_hooks.c driver.c @@ -45,7 +44,7 @@ KernelStaticLibrary libfreebsd_network.a : priv.cpp smp.c subr_autoconf.cpp - synch.c + synch.cpp systm.cpp sysinit.c taskqueue.c diff --git a/src/libs/compat/freebsd_network/compat/sys/systm.h b/src/libs/compat/freebsd_network/compat/sys/systm.h index 7ae6d90d12..b4d3b113a9 100644 --- a/src/libs/compat/freebsd_network/compat/sys/systm.h +++ b/src/libs/compat/freebsd_network/compat/sys/systm.h @@ -99,8 +99,6 @@ extern int vsnprintf(char *, size_t, const char *, __va_list) int msleep(void *, struct mtx *, int, const char *, int); int _pause(const char *, int); #define pause(waitMessage, timeout) _pause((waitMessage), (timeout)) -#define tsleep(channel, priority, waitMessage, timeout) \ - msleep((channel), NULL, (priority), (waitMessage), (timeout)) #define msleep_spin(chan, mtx, wmesg, timo) \ msleep(chan, mtx, PZERO, wmesg, timo) #define mtx_sleep msleep diff --git a/src/libs/compat/freebsd_network/condvar.c b/src/libs/compat/freebsd_network/condvar.c deleted file mode 100644 index 79f1062d3a..0000000000 --- a/src/libs/compat/freebsd_network/condvar.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2009 Colin Günther, coling@gmx.de. - * All rights reserved. Distributed under the terms of the MIT License. - */ - - -#include -#include - -#include "Condvar.h" - - -void cv_init(struct cv* variable, const char* description) -{ - conditionInit(variable, description); -} - - -void cv_signal(struct cv* variable) -{ - conditionNotifyOne(variable); -} - - -int cv_timedwait(struct cv* variable, struct mtx* mutex, int timeout) -{ - int status; - - mtx_unlock(mutex); - status = conditionTimedWait(variable, timeout); - mtx_lock(mutex); - - return status; -} - - -void cv_wait(struct cv* variable, struct mtx* mutex) -{ - mtx_unlock(mutex); - conditionWait(variable); - mtx_lock(mutex); -} diff --git a/src/libs/compat/freebsd_network/condvar.cpp b/src/libs/compat/freebsd_network/condvar.cpp new file mode 100644 index 0000000000..a8e5ad6e4b --- /dev/null +++ b/src/libs/compat/freebsd_network/condvar.cpp @@ -0,0 +1,56 @@ +/* + * Copyright 2022, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT license. + */ + +#include +#include +#include + + +void +cv_init(struct cv* variable, const char* description) +{ + variable->condition.Init(NULL, description); +} + + +void +cv_signal(struct cv* variable) +{ + variable->condition.NotifyOne(); +} + + +int +cv_timedwait(struct cv* variable, struct mtx* mutex, int timeout) +{ + int status; + + const uint32 flags = timeout ? B_RELATIVE_TIMEOUT : 0; + const bigtime_t bigtimeout = TICKS_2_USEC(timeout); + + if (mutex->type == MTX_RECURSE) { + // Special case: let the ConditionVariable handle switching recursive locks. + status = variable->condition.Wait(&mutex->u.recursive, + flags, bigtimeout); + return status; + } + + ConditionVariableEntry entry; + variable->condition.Add(&entry); + + mtx_unlock(mutex); + + status = entry.Wait(flags, bigtimeout); + + mtx_lock(mutex); + return status; +} + + +void +cv_wait(struct cv* variable, struct mtx* mutex) +{ + cv_timedwait(variable, mutex, 0); +} diff --git a/src/libs/compat/freebsd_network/synch.c b/src/libs/compat/freebsd_network/synch.c deleted file mode 100644 index d187915930..0000000000 --- a/src/libs/compat/freebsd_network/synch.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 -#include -#include - -#include "Condvar.h" - - -int -msleep(void* identifier, struct mtx* mutex, int priority, - const char* description, int timeout) -{ - int status; - struct cv sleep; - - conditionPublish(&sleep, identifier, description); - - // FreeBSD's msleep() does not allow the mutex to be NULL, but we - // do, as we implement some other functions like tsleep() with it. - if (mutex != NULL) - mtx_unlock(mutex); - - status = publishedConditionTimedWait(identifier, timeout); - - if (mutex != NULL) - mtx_lock(mutex); - - conditionUnpublish(&sleep); - - return status; -} - - -void -wakeup(void* identifier) -{ - publishedConditionNotifyAll(identifier); -} - - -void -wakeup_one(void* identifier) -{ - publishedConditionNotifyOne(identifier); -} diff --git a/src/libs/compat/freebsd_network/synch.cpp b/src/libs/compat/freebsd_network/synch.cpp new file mode 100644 index 0000000000..94de255b63 --- /dev/null +++ b/src/libs/compat/freebsd_network/synch.cpp @@ -0,0 +1,37 @@ +/* + * Copyright 2022, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT license. + */ + +#include +#include +#include +#include + + +int +msleep(void* identifier, struct mtx* mutex, int priority, + const char* description, int timeout) +{ + struct cv channel; + channel.condition.Publish(identifier, description); + + int status = cv_timedwait(&channel, mutex, timeout); + + channel.condition.Unpublish(); + return status; +} + + +void +wakeup(void* identifier) +{ + ConditionVariable::NotifyAll(identifier, B_OK); +} + + +void +wakeup_one(void* identifier) +{ + ConditionVariable::NotifyOne(identifier, B_OK); +}