diff options
author | Nicolai Hähnle <nicolai.haehnle@amd.com> | 2017-10-22 17:38:40 +0200 |
---|---|---|
committer | Nicolai Hähnle <nicolai.haehnle@amd.com> | 2017-11-03 19:39:11 +0100 |
commit | aa5b52b85f552eb9f6281125ed1bea9da081f9d4 (patch) | |
tree | 6bde005dbfb9feae639a4ce67120c43567ff1e50 | |
parent | 928ee1fb050d77b80f37c4bb44a6b273ba7b2046 (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 <marek.olsak@amd.com>
-rw-r--r-- | src/gallium/auxiliary/os/os_thread.h | 76 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_rast.c | 9 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_rast_priv.h | 4 | ||||
-rw-r--r-- | src/gallium/tests/unit/pipe_barrier_test.c | 12 | ||||
-rw-r--r-- | src/util/u_thread.h | 74 |
5 files changed, 87 insertions, 88 deletions
diff --git a/src/gallium/auxiliary/os/os_thread.h b/src/gallium/auxiliary/os/os_thread.h index 10d4695da6..d9c685922a 100644 --- a/src/gallium/auxiliary/os/os_thread.h +++ b/src/gallium/auxiliary/os/os_thread.h @@ -61,82 +61,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 0050655d9e..9e2780ca1d 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 3cc52b8d4f..fe078d5b86 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 58ad7e2963..6bd46b8d96 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 <stdio.h> #include <stdlib.h> -#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 6b5458af86..e484d8aa74 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_ */ |