unsigned gomp_resolve_num_threads (unsigned specified) { /* Early exit for false IF condition or degenerate NUM_THREADS. */ if (specified == 1) return 1; /* If this is a nested region, and nested regions are disabled, force this team to use only one thread. */ if (gomp_thread()->ts.team && !gomp_nest_var) return 1; /* If NUM_THREADS not specified, use nthreads_var. */ if (specified == 0) specified = gomp_nthreads_var; /* If dynamic threads are enabled, bound the number of threads that we launch. */ if (gomp_dyn_var) { unsigned dyn = gomp_dynamic_max_threads (); if (dyn < specified) return dyn; } return specified; }
unsigned gomp_resolve_num_threads (unsigned specified, unsigned count) { struct gomp_thread *thr = gomp_thread (); struct gomp_task_icv *icv; unsigned threads_requested, max_num_threads, num_threads; unsigned long busy; struct gomp_thread_pool *pool; icv = gomp_icv (false); if (specified == 1) return 1; else if (thr->ts.active_level >= 1 && !icv->nest_var) return 1; else if (thr->ts.active_level >= gomp_max_active_levels_var) return 1; /* If NUM_THREADS not specified, use nthreads_var. */ if (specified == 0) threads_requested = icv->nthreads_var; else threads_requested = specified; max_num_threads = threads_requested; /* If dynamic threads are enabled, bound the number of threads that we launch. */ if (icv->dyn_var) { unsigned dyn = gomp_dynamic_max_threads (); if (dyn < max_num_threads) max_num_threads = dyn; /* Optimization for parallel sections. */ if (count && count < max_num_threads) max_num_threads = count; } /* UINT_MAX stands for infinity. */ if (__builtin_expect (icv->thread_limit_var == UINT_MAX, 1) || max_num_threads == 1) return max_num_threads; /* The threads_busy counter lives in thread_pool, if there isn't a thread_pool yet, there must be just one thread in the contention group. If thr->team is NULL, this isn't nested parallel, so there is just one thread in the contention group as well, no need to handle it atomically. */ pool = thr->thread_pool; if (thr->ts.team == NULL || pool == NULL) { num_threads = max_num_threads; if (num_threads > icv->thread_limit_var) num_threads = icv->thread_limit_var; if (pool) pool->threads_busy = num_threads; return num_threads; } #ifdef HAVE_SYNC_BUILTINS do { busy = pool->threads_busy; num_threads = max_num_threads; if (icv->thread_limit_var - busy + 1 < num_threads) num_threads = icv->thread_limit_var - busy + 1; } while (__sync_val_compare_and_swap (&pool->threads_busy, busy, busy + num_threads - 1) != busy); #else gomp_mutex_lock (&gomp_managed_threads_lock); num_threads = max_num_threads; busy = pool->threads_busy; if (icv->thread_limit_var - busy + 1 < num_threads) num_threads = icv->thread_limit_var - busy + 1; pool->threads_busy += num_threads - 1; gomp_mutex_unlock (&gomp_managed_threads_lock); #endif return num_threads; }
unsigned gomp_resolve_num_threads (unsigned specified, unsigned count) { struct gomp_thread *thread = gomp_thread(); struct gomp_task_icv *icv; unsigned threads_requested, max_num_threads, num_threads; unsigned long remaining; icv = gomp_icv (false); if (specified == 1) return 1; else if (thread->ts.active_level >= 1 && !icv->nest_var) return 1; else if (thread->ts.active_level >= gomp_max_active_levels_var) return 1; /* If NUM_THREADS not specified, use nthreads_var. */ if (specified == 0) threads_requested = icv->nthreads_var; else threads_requested = specified; max_num_threads = threads_requested; /* If dynamic threads are enabled, bound the number of threads that we launch. */ if (icv->dyn_var) { unsigned dyn = gomp_dynamic_max_threads (); if (dyn < max_num_threads) max_num_threads = dyn; /* Optimization for parallel sections. */ if (count && count < max_num_threads) max_num_threads = count; } /* ULONG_MAX stands for infinity. */ if (__builtin_expect (gomp_thread_limit_var == ULONG_MAX, 1) || max_num_threads == 1) return max_num_threads; #ifdef HAVE_SYNC_BUILTINS do { remaining = gomp_remaining_threads_count; num_threads = max_num_threads; if (num_threads > remaining) num_threads = remaining + 1; } while (__sync_val_compare_and_swap (&gomp_remaining_threads_count, remaining, remaining - num_threads + 1) != remaining); #else gomp_mutex_lock (&gomp_remaining_threads_lock); num_threads = max_num_threads; remaining = gomp_remaining_threads_count; if (num_threads > remaining) num_threads = remaining + 1; gomp_remaining_threads_count -= num_threads - 1; gomp_mutex_unlock (&gomp_remaining_threads_lock); #endif return num_threads; }