X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Futil%2Fsimple_mtx.h;h=1bd57ac800195f117bc0859c74b333f5c3ffc8e0;hb=56d76859fa5d31be8fee707f44f5dfdadce53cdd;hp=86ba026e61c5c88d17feea586792da03d348d6fa;hpb=f98a2768ca0609fb81a0ee8f30ac1e70269334c4;p=mesa.git diff --git a/src/util/simple_mtx.h b/src/util/simple_mtx.h index 86ba026e61c..1bd57ac8001 100644 --- a/src/util/simple_mtx.h +++ b/src/util/simple_mtx.h @@ -24,9 +24,12 @@ #ifndef _SIMPLE_MTX_H #define _SIMPLE_MTX_H +#include "util/futex.h" +#include "util/macros.h" + #include "c11/threads.h" -#if defined(__GNUC__) && defined(HAVE_LINUX_FUTEX_H) +#if UTIL_FUTEX_SUPPORTED /* mtx_t - Fast, simple mutex * @@ -58,29 +61,10 @@ typedef struct { #define _SIMPLE_MTX_INITIALIZER_NP { 0 } -#include -#include -#include -#include - -static inline long sys_futex(void *addr1, int op, int val1, - struct timespec *timeout, void *addr2, int val3) -{ - return syscall(SYS_futex, addr1, op, val1, timeout, addr2, val3); -} - -static inline int futex_wake(uint32_t *addr, int count) -{ - return sys_futex(addr, FUTEX_WAKE, count, NULL, NULL, 0); -} - -static inline int futex_wait(uint32_t *addr, int32_t value) -{ - return sys_futex(addr, FUTEX_WAIT, value, NULL, NULL, 0); -} +#define _SIMPLE_MTX_INVALID_VALUE 0xd0d0d0d0 static inline void -simple_mtx_init(simple_mtx_t *mtx, int type) +simple_mtx_init(simple_mtx_t *mtx, ASSERTED int type) { assert(type == mtx_plain); @@ -88,8 +72,11 @@ simple_mtx_init(simple_mtx_t *mtx, int type) } static inline void -simple_mtx_destroy(simple_mtx_t *mtx) +simple_mtx_destroy(ASSERTED simple_mtx_t *mtx) { +#ifndef NDEBUG + mtx->val = _SIMPLE_MTX_INVALID_VALUE; +#endif } static inline void @@ -98,11 +85,14 @@ simple_mtx_lock(simple_mtx_t *mtx) uint32_t c; c = __sync_val_compare_and_swap(&mtx->val, 0, 1); + + assert(c != _SIMPLE_MTX_INVALID_VALUE); + if (__builtin_expect(c != 0, 0)) { if (c != 2) c = __sync_lock_test_and_set(&mtx->val, 2); while (c != 0) { - futex_wait(&mtx->val, 2); + futex_wait(&mtx->val, 2, NULL); c = __sync_lock_test_and_set(&mtx->val, 2); } } @@ -114,12 +104,21 @@ simple_mtx_unlock(simple_mtx_t *mtx) uint32_t c; c = __sync_fetch_and_sub(&mtx->val, 1); + + assert(c != _SIMPLE_MTX_INVALID_VALUE); + if (__builtin_expect(c != 1, 0)) { mtx->val = 0; futex_wake(&mtx->val, 1); } } +static inline void +simple_mtx_assert_locked(simple_mtx_t *mtx) +{ + assert(mtx->val); +} + #else typedef mtx_t simple_mtx_t; @@ -150,6 +149,22 @@ simple_mtx_unlock(simple_mtx_t *mtx) mtx_unlock(mtx); } +static inline void +simple_mtx_assert_locked(simple_mtx_t *mtx) +{ +#ifdef DEBUG + /* NOTE: this would not work for recursive mutexes, but + * mtx_t doesn't support those + */ + int ret = mtx_trylock(mtx); + assert(ret == thrd_busy); + if (ret == thrd_success) + mtx_unlock(mtx); +#else + (void)mtx; +#endif +} + #endif #endif