From 7dc2f4788288ec9c7ab63e37fdea750c08503eca Mon Sep 17 00:00:00 2001 From: Greg V Date: Sun, 24 Dec 2017 19:55:46 +0300 Subject: util: emulate futex on FreeBSD using umtx Obtained from: FreeBSD ports Acked-by: Emil Velikov Acked-by: Eric Engestrom --- src/util/futex.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/util/futex.h b/src/util/futex.h index 4402893069d..a8b2c0f3527 100644 --- a/src/util/futex.h +++ b/src/util/futex.h @@ -51,6 +51,40 @@ static inline int futex_wait(uint32_t *addr, int32_t value, const struct timespe FUTEX_BITSET_MATCH_ANY); } +#elif defined(__FreeBSD__) + +#include +#include +#include +#include +#include +#include + +static inline int futex_wake(uint32_t *addr, int count) +{ + assert(count == (int)(uint32_t)count); /* Check that bits weren't discarded */ + return _umtx_op(addr, UMTX_OP_WAKE, (uint32_t)count, NULL, NULL) == -1 ? errno : 0; +} + +static inline int futex_wait(uint32_t *addr, int32_t value, struct timespec *timeout) +{ + void *uaddr = NULL, *uaddr2 = NULL; + + assert(value == (int)(uint32_t)value); /* Check that bits weren't discarded */ + + if (timeout != NULL) { + const struct _umtx_time tmo = { + ._timeout = *timeout, + ._flags = UMTX_ABSTIME, + ._clockid = CLOCK_MONOTONIC + }; + uaddr = (void *)(uintptr_t)sizeof(tmo); + uaddr2 = (void *)&tmo; + } + + return _umtx_op(addr, UMTX_OP_WAIT_UINT, (uint32_t)value, uaddr, uaddr2) == -1 ? errno : 0; +} + #endif #endif /* UTIL_FUTEX_H */ -- cgit v1.2.3