From: Nicolai Hähnle Date: Sun, 22 Oct 2017 15:38:40 +0000 (+0200) Subject: util: move pipe_barrier into src/util and rename to util_barrier X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f0d3a4de75fdb865c058aba8614f0fe6ba5f0969;p=mesa.git 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 --- diff --git a/src/gallium/auxiliary/os/os_thread.h b/src/gallium/auxiliary/os/os_thread.h index 10d4695da68..d9c685922a5 100644 --- a/src/gallium/auxiliary/os/os_thread.h +++ b/src/gallium/auxiliary/os/os_thread.h @@ -60,82 +60,6 @@ __pipe_mutex_assert_locked(mtx_t *mutex) } -/* - * pipe_barrier - */ - -#if (defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_HURD)) && (!defined(PIPE_OS_ANDROID) || ANDROID_API_LEVEL >= 24) - -typedef pthread_barrier_t pipe_barrier; - -static inline void pipe_barrier_init(pipe_barrier *barrier, unsigned count) -{ - pthread_barrier_init(barrier, NULL, count); -} - -static inline void pipe_barrier_destroy(pipe_barrier *barrier) -{ - pthread_barrier_destroy(barrier); -} - -static inline void pipe_barrier_wait(pipe_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; -} pipe_barrier; - -static inline void pipe_barrier_init(pipe_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 pipe_barrier_destroy(pipe_barrier *barrier) -{ - assert(barrier->waiters == 0); - mtx_destroy(&barrier->mutex); - cnd_destroy(&barrier->condvar); -} - -static inline void pipe_barrier_wait(pipe_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 - - /* * Semaphores */ diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 0050655d9e3..9e2780ca1d7 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -32,6 +32,7 @@ #include "util/u_surface.h" #include "util/u_pack_color.h" #include "util/u_string.h" +#include "util/u_thread.h" #include "os/os_time.h" @@ -822,7 +823,7 @@ thread_function(void *init_data) /* Wait for all threads to get here so that threads[1+] don't * get a null rast->curr_scene pointer. */ - pipe_barrier_wait( &rast->barrier ); + util_barrier_wait( &rast->barrier ); /* do work */ if (debug) @@ -832,7 +833,7 @@ thread_function(void *init_data) rast->curr_scene); /* wait for all threads to finish with this scene */ - pipe_barrier_wait( &rast->barrier ); + util_barrier_wait( &rast->barrier ); /* XXX: shouldn't be necessary: */ @@ -914,7 +915,7 @@ lp_rast_create( unsigned num_threads ) /* for synchronizing rasterization threads */ if (rast->num_threads > 0) { - pipe_barrier_init( &rast->barrier, rast->num_threads ); + util_barrier_init( &rast->barrier, rast->num_threads ); } memset(lp_dummy_tile, 0, sizeof lp_dummy_tile); @@ -973,7 +974,7 @@ void lp_rast_destroy( struct lp_rasterizer *rast ) /* for synchronizing rasterization threads */ if (rast->num_threads > 0) { - pipe_barrier_destroy( &rast->barrier ); + util_barrier_destroy( &rast->barrier ); } lp_scene_queue_destroy(rast->full_scenes); diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index 3cc52b8d4fd..fe078d5b869 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -28,8 +28,8 @@ #ifndef LP_RAST_PRIV_H #define LP_RAST_PRIV_H -#include "os/os_thread.h" #include "util/u_format.h" +#include "util/u_thread.h" #include "gallivm/lp_bld_debug.h" #include "lp_memory.h" #include "lp_rast.h" @@ -130,7 +130,7 @@ struct lp_rasterizer thrd_t threads[LP_MAX_THREADS]; /** For synchronizing the rasterization threads */ - pipe_barrier barrier; + util_barrier barrier; }; diff --git a/src/gallium/tests/unit/pipe_barrier_test.c b/src/gallium/tests/unit/pipe_barrier_test.c index 58ad7e29630..6bd46b8d964 100644 --- a/src/gallium/tests/unit/pipe_barrier_test.c +++ b/src/gallium/tests/unit/pipe_barrier_test.c @@ -27,7 +27,7 @@ /* - * Test case for pipe_barrier. + * Test case for util_barrier. * * The test succeeds if no thread exits before all the other threads reach * the barrier. @@ -37,9 +37,9 @@ #include #include -#include "os/os_thread.h" #include "os/os_time.h" #include "util/u_atomic.h" +#include "util/u_thread.h" #define NUM_THREADS 10 @@ -47,7 +47,7 @@ static int verbosity = 0; static thrd_t threads[NUM_THREADS]; -static pipe_barrier barrier; +static util_barrier barrier; static int thread_ids[NUM_THREADS]; static volatile int waiting = 0; @@ -78,7 +78,7 @@ thread_function(void *thread_data) CHECK(p_atomic_read(&proceeded) == 0); p_atomic_inc(&waiting); - pipe_barrier_wait(&barrier); + util_barrier_wait(&barrier); CHECK(p_atomic_read(&waiting) == NUM_THREADS); @@ -109,7 +109,7 @@ int main(int argc, char *argv[]) LOG("pipe_barrier_test starting\n"); - pipe_barrier_init(&barrier, NUM_THREADS); + util_barrier_init(&barrier, NUM_THREADS); for (i = 0; i < NUM_THREADS; i++) { thread_ids[i] = i; @@ -122,7 +122,7 @@ int main(int argc, char *argv[]) CHECK(p_atomic_read(&proceeded) == NUM_THREADS); - pipe_barrier_destroy(&barrier); + util_barrier_destroy(&barrier); LOG("pipe_barrier_test exiting\n"); 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_ */