summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg V <[email protected]>2017-12-24 19:55:46 +0300
committerEric Engestrom <[email protected]>2019-03-03 19:48:49 +0000
commit7dc2f4788288ec9c7ab63e37fdea750c08503eca (patch)
tree9520c79d0cee45d00ec379d81456986bc41658d7
parent00f838fa730f5c765902fe2e5ce9754df5276e91 (diff)
util: emulate futex on FreeBSD using umtx
Obtained from: FreeBSD ports Acked-by: Emil Velikov <[email protected]> Acked-by: Eric Engestrom <[email protected]>
-rw-r--r--src/util/futex.h34
1 files changed, 34 insertions, 0 deletions
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 <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/umtx.h>
+#include <sys/time.h>
+
+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 */