From 914bd3014f6cb05f0893485487e69ca87e7c972c Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Wed, 12 Sep 2018 20:29:19 -0400 Subject: gallium/util: don't let child processes inherit our thread affinity v2: corrected the comment --- src/gallium/auxiliary/util/u_helpers.c | 36 ++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/gallium/auxiliary/util/u_helpers.c b/src/gallium/auxiliary/util/u_helpers.c index 14367e5a118..b6cebf96329 100644 --- a/src/gallium/auxiliary/util/u_helpers.c +++ b/src/gallium/auxiliary/util/u_helpers.c @@ -121,17 +121,40 @@ util_upload_index_buffer(struct pipe_context *pipe, return *out_buffer != NULL; } +#ifdef HAVE_PTHREAD_SETAFFINITY + static unsigned L3_cache_number; -static once_flag init_cache_number_flag = ONCE_FLAG_INIT; +static once_flag thread_pinning_once_flag = ONCE_FLAG_INIT; + +static void +util_set_full_cpu_affinity(void) +{ + cpu_set_t cpuset; + + CPU_ZERO(&cpuset); + for (unsigned i = 0; i < CPU_SETSIZE; i++) + CPU_SET(i, &cpuset); + + pthread_setaffinity_np(pthread_self(), sizeof(cpuset), &cpuset); +} static void -util_init_cache_number(void) +util_init_thread_pinning(void) { /* Get a semi-random number. */ int64_t t = os_time_get_nano(); L3_cache_number = (t ^ (t >> 8) ^ (t >> 16)); + + /* Reset thread affinity for all child processes to prevent them from + * inheriting the current thread's affinity. + * + * What happens if a driver is unloaded and the app creates a thread? + */ + pthread_atfork(NULL, NULL, util_set_full_cpu_affinity); } +#endif + /** * Called by MakeCurrent. Used to notify the driver that the application * thread may have been changed. @@ -146,18 +169,23 @@ util_init_cache_number(void) void util_context_thread_changed(struct pipe_context *ctx, thrd_t *upper_thread) { -#ifdef HAVE_PTHREAD +#ifdef HAVE_PTHREAD_SETAFFINITY + /* If pinning has no effect, don't do anything. */ + if (util_cpu_caps.nr_cpus == util_cpu_caps.cores_per_L3) + return; + thrd_t current = thrd_current(); int cache = util_get_L3_for_pinned_thread(current, util_cpu_caps.cores_per_L3); + call_once(&thread_pinning_once_flag, util_init_thread_pinning); + /* If the main thread is not pinned, choose the L3 cache. */ if (cache == -1) { unsigned num_L3_caches = util_cpu_caps.nr_cpus / util_cpu_caps.cores_per_L3; /* Choose a different L3 cache for each subsequent MakeCurrent. */ - call_once(&init_cache_number_flag, util_init_cache_number); cache = p_atomic_inc_return(&L3_cache_number) % num_L3_caches; util_pin_thread_to_L3(current, cache, util_cpu_caps.cores_per_L3); } -- cgit v1.2.3