diff options
author | Nicolai Hähnle <[email protected]> | 2017-10-22 17:38:40 +0200 |
---|---|---|
committer | Nicolai Hähnle <[email protected]> | 2017-11-09 11:53:19 +0100 |
commit | f0d3a4de75fdb865c058aba8614f0fe6ba5f0969 (patch) | |
tree | 282bc069bd4f0a566adaef1cfcc66e0c9cff32ea /src/util | |
parent | 28c95cdb299f56c8224446368fb464b7b1d44a6c (diff) |
util: move pipe_barrier into src/util and rename to util_barrier
The #if guard is probably not 100% equivalent to the previous PIPE_OS
check, but if anything it should be an over-approximation (are there
pthread implementations without barriers?), so people will get either
a good implementation or compile errors that are easy to fix.
Reviewed-by: Marek Olšák <[email protected]>
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/u_thread.h | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/src/util/u_thread.h b/src/util/u_thread.h index 6b5458af86a..e484d8aa74f 100644 --- a/src/util/u_thread.h +++ b/src/util/u_thread.h @@ -100,4 +100,78 @@ static inline bool u_thread_is_self(thrd_t thread) return false; } +/* + * util_barrier + */ + +#if defined(HAVE_PTHREAD) + +typedef pthread_barrier_t util_barrier; + +static inline void util_barrier_init(util_barrier *barrier, unsigned count) +{ + pthread_barrier_init(barrier, NULL, count); +} + +static inline void util_barrier_destroy(util_barrier *barrier) +{ + pthread_barrier_destroy(barrier); +} + +static inline void util_barrier_wait(util_barrier *barrier) +{ + pthread_barrier_wait(barrier); +} + + +#else /* If the OS doesn't have its own, implement barriers using a mutex and a condvar */ + +typedef struct { + unsigned count; + unsigned waiters; + uint64_t sequence; + mtx_t mutex; + cnd_t condvar; +} util_barrier; + +static inline void util_barrier_init(util_barrier *barrier, unsigned count) +{ + barrier->count = count; + barrier->waiters = 0; + barrier->sequence = 0; + (void) mtx_init(&barrier->mutex, mtx_plain); + cnd_init(&barrier->condvar); +} + +static inline void util_barrier_destroy(util_barrier *barrier) +{ + assert(barrier->waiters == 0); + mtx_destroy(&barrier->mutex); + cnd_destroy(&barrier->condvar); +} + +static inline void util_barrier_wait(util_barrier *barrier) +{ + mtx_lock(&barrier->mutex); + + assert(barrier->waiters < barrier->count); + barrier->waiters++; + + if (barrier->waiters < barrier->count) { + uint64_t sequence = barrier->sequence; + + do { + cnd_wait(&barrier->condvar, &barrier->mutex); + } while (sequence == barrier->sequence); + } else { + barrier->waiters = 0; + barrier->sequence++; + cnd_broadcast(&barrier->condvar); + } + + mtx_unlock(&barrier->mutex); +} + +#endif + #endif /* U_THREAD_H_ */ |