Home | History | Annotate | Line # | Download | only in libgomp
team.c revision 1.1.1.9
      1  1.1.1.9  mrg /* Copyright (C) 2005-2019 Free Software Foundation, Inc.
      2      1.1  mrg    Contributed by Richard Henderson <rth (at) redhat.com>.
      3      1.1  mrg 
      4  1.1.1.3  mrg    This file is part of the GNU Offloading and Multi Processing Library
      5  1.1.1.3  mrg    (libgomp).
      6      1.1  mrg 
      7      1.1  mrg    Libgomp is free software; you can redistribute it and/or modify it
      8      1.1  mrg    under the terms of the GNU General Public License as published by
      9      1.1  mrg    the Free Software Foundation; either version 3, or (at your option)
     10      1.1  mrg    any later version.
     11      1.1  mrg 
     12      1.1  mrg    Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
     13      1.1  mrg    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
     14      1.1  mrg    FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
     15      1.1  mrg    more details.
     16      1.1  mrg 
     17      1.1  mrg    Under Section 7 of GPL version 3, you are granted additional
     18      1.1  mrg    permissions described in the GCC Runtime Library Exception, version
     19      1.1  mrg    3.1, as published by the Free Software Foundation.
     20      1.1  mrg 
     21      1.1  mrg    You should have received a copy of the GNU General Public License and
     22      1.1  mrg    a copy of the GCC Runtime Library Exception along with this program;
     23      1.1  mrg    see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     24      1.1  mrg    <http://www.gnu.org/licenses/>.  */
     25      1.1  mrg 
     26      1.1  mrg /* This file handles the maintainence of threads in response to team
     27      1.1  mrg    creation and termination.  */
     28      1.1  mrg 
     29      1.1  mrg #include "libgomp.h"
     30  1.1.1.4  mrg #include "pool.h"
     31      1.1  mrg #include <stdlib.h>
     32      1.1  mrg #include <string.h>
     33      1.1  mrg 
     34  1.1.1.5  mrg #ifdef LIBGOMP_USE_PTHREADS
     35      1.1  mrg pthread_attr_t gomp_thread_attr;
     36      1.1  mrg 
     37      1.1  mrg /* This key is for the thread destructor.  */
     38      1.1  mrg pthread_key_t gomp_thread_destructor;
     39      1.1  mrg 
     40      1.1  mrg 
     41      1.1  mrg /* This is the libgomp per-thread data structure.  */
     42  1.1.1.3  mrg #if defined HAVE_TLS || defined USE_EMUTLS
     43      1.1  mrg __thread struct gomp_thread gomp_tls_data;
     44      1.1  mrg #else
     45      1.1  mrg pthread_key_t gomp_tls_key;
     46      1.1  mrg #endif
     47      1.1  mrg 
     48      1.1  mrg 
     49      1.1  mrg /* This structure is used to communicate across pthread_create.  */
     50      1.1  mrg 
     51      1.1  mrg struct gomp_thread_start_data
     52      1.1  mrg {
     53      1.1  mrg   void (*fn) (void *);
     54      1.1  mrg   void *fn_data;
     55      1.1  mrg   struct gomp_team_state ts;
     56      1.1  mrg   struct gomp_task *task;
     57      1.1  mrg   struct gomp_thread_pool *thread_pool;
     58  1.1.1.3  mrg   unsigned int place;
     59      1.1  mrg   bool nested;
     60  1.1.1.9  mrg   pthread_t handle;
     61      1.1  mrg };
     62      1.1  mrg 
     63      1.1  mrg 
     64      1.1  mrg /* This function is a pthread_create entry point.  This contains the idle
     65      1.1  mrg    loop in which a thread waits to be called up to become part of a team.  */
     66      1.1  mrg 
     67      1.1  mrg static void *
     68      1.1  mrg gomp_thread_start (void *xdata)
     69      1.1  mrg {
     70      1.1  mrg   struct gomp_thread_start_data *data = xdata;
     71      1.1  mrg   struct gomp_thread *thr;
     72      1.1  mrg   struct gomp_thread_pool *pool;
     73      1.1  mrg   void (*local_fn) (void *);
     74      1.1  mrg   void *local_data;
     75      1.1  mrg 
     76  1.1.1.3  mrg #if defined HAVE_TLS || defined USE_EMUTLS
     77      1.1  mrg   thr = &gomp_tls_data;
     78      1.1  mrg #else
     79      1.1  mrg   struct gomp_thread local_thr;
     80      1.1  mrg   thr = &local_thr;
     81      1.1  mrg   pthread_setspecific (gomp_tls_key, thr);
     82      1.1  mrg #endif
     83      1.1  mrg   gomp_sem_init (&thr->release, 0);
     84      1.1  mrg 
     85      1.1  mrg   /* Extract what we need from data.  */
     86      1.1  mrg   local_fn = data->fn;
     87      1.1  mrg   local_data = data->fn_data;
     88      1.1  mrg   thr->thread_pool = data->thread_pool;
     89      1.1  mrg   thr->ts = data->ts;
     90      1.1  mrg   thr->task = data->task;
     91  1.1.1.3  mrg   thr->place = data->place;
     92  1.1.1.9  mrg #ifdef GOMP_NEEDS_THREAD_HANDLE
     93  1.1.1.9  mrg   thr->handle = data->handle;
     94  1.1.1.9  mrg #endif
     95      1.1  mrg 
     96      1.1  mrg   thr->ts.team->ordered_release[thr->ts.team_id] = &thr->release;
     97      1.1  mrg 
     98      1.1  mrg   /* Make thread pool local. */
     99      1.1  mrg   pool = thr->thread_pool;
    100      1.1  mrg 
    101      1.1  mrg   if (data->nested)
    102      1.1  mrg     {
    103      1.1  mrg       struct gomp_team *team = thr->ts.team;
    104      1.1  mrg       struct gomp_task *task = thr->task;
    105      1.1  mrg 
    106      1.1  mrg       gomp_barrier_wait (&team->barrier);
    107      1.1  mrg 
    108      1.1  mrg       local_fn (local_data);
    109  1.1.1.3  mrg       gomp_team_barrier_wait_final (&team->barrier);
    110      1.1  mrg       gomp_finish_task (task);
    111      1.1  mrg       gomp_barrier_wait_last (&team->barrier);
    112      1.1  mrg     }
    113      1.1  mrg   else
    114      1.1  mrg     {
    115      1.1  mrg       pool->threads[thr->ts.team_id] = thr;
    116      1.1  mrg 
    117  1.1.1.5  mrg       gomp_simple_barrier_wait (&pool->threads_dock);
    118      1.1  mrg       do
    119      1.1  mrg 	{
    120      1.1  mrg 	  struct gomp_team *team = thr->ts.team;
    121      1.1  mrg 	  struct gomp_task *task = thr->task;
    122      1.1  mrg 
    123      1.1  mrg 	  local_fn (local_data);
    124  1.1.1.3  mrg 	  gomp_team_barrier_wait_final (&team->barrier);
    125      1.1  mrg 	  gomp_finish_task (task);
    126      1.1  mrg 
    127  1.1.1.5  mrg 	  gomp_simple_barrier_wait (&pool->threads_dock);
    128      1.1  mrg 
    129      1.1  mrg 	  local_fn = thr->fn;
    130      1.1  mrg 	  local_data = thr->data;
    131      1.1  mrg 	  thr->fn = NULL;
    132      1.1  mrg 	}
    133      1.1  mrg       while (local_fn);
    134      1.1  mrg     }
    135      1.1  mrg 
    136      1.1  mrg   gomp_sem_destroy (&thr->release);
    137  1.1.1.9  mrg   pthread_detach (pthread_self ());
    138  1.1.1.3  mrg   thr->thread_pool = NULL;
    139  1.1.1.3  mrg   thr->task = NULL;
    140      1.1  mrg   return NULL;
    141      1.1  mrg }
    142  1.1.1.5  mrg #endif
    143      1.1  mrg 
    144  1.1.1.4  mrg static inline struct gomp_team *
    145  1.1.1.4  mrg get_last_team (unsigned nthreads)
    146  1.1.1.4  mrg {
    147  1.1.1.4  mrg   struct gomp_thread *thr = gomp_thread ();
    148  1.1.1.4  mrg   if (thr->ts.team == NULL)
    149  1.1.1.4  mrg     {
    150  1.1.1.4  mrg       struct gomp_thread_pool *pool = gomp_get_thread_pool (thr, nthreads);
    151  1.1.1.4  mrg       struct gomp_team *last_team = pool->last_team;
    152  1.1.1.4  mrg       if (last_team != NULL && last_team->nthreads == nthreads)
    153  1.1.1.4  mrg         {
    154  1.1.1.4  mrg           pool->last_team = NULL;
    155  1.1.1.4  mrg           return last_team;
    156  1.1.1.4  mrg         }
    157  1.1.1.4  mrg     }
    158  1.1.1.4  mrg   return NULL;
    159  1.1.1.4  mrg }
    160      1.1  mrg 
    161      1.1  mrg /* Create a new team data structure.  */
    162      1.1  mrg 
    163      1.1  mrg struct gomp_team *
    164      1.1  mrg gomp_new_team (unsigned nthreads)
    165      1.1  mrg {
    166      1.1  mrg   struct gomp_team *team;
    167      1.1  mrg   int i;
    168      1.1  mrg 
    169  1.1.1.4  mrg   team = get_last_team (nthreads);
    170  1.1.1.4  mrg   if (team == NULL)
    171  1.1.1.4  mrg     {
    172  1.1.1.4  mrg       size_t extra = sizeof (team->ordered_release[0])
    173  1.1.1.4  mrg 		     + sizeof (team->implicit_task[0]);
    174  1.1.1.4  mrg       team = gomp_malloc (sizeof (*team) + nthreads * extra);
    175  1.1.1.4  mrg 
    176  1.1.1.4  mrg #ifndef HAVE_SYNC_BUILTINS
    177  1.1.1.4  mrg       gomp_mutex_init (&team->work_share_list_free_lock);
    178  1.1.1.4  mrg #endif
    179  1.1.1.4  mrg       gomp_barrier_init (&team->barrier, nthreads);
    180  1.1.1.4  mrg       gomp_mutex_init (&team->task_lock);
    181  1.1.1.4  mrg 
    182  1.1.1.4  mrg       team->nthreads = nthreads;
    183  1.1.1.4  mrg     }
    184      1.1  mrg 
    185      1.1  mrg   team->work_share_chunk = 8;
    186      1.1  mrg #ifdef HAVE_SYNC_BUILTINS
    187      1.1  mrg   team->single_count = 0;
    188      1.1  mrg #endif
    189  1.1.1.3  mrg   team->work_shares_to_free = &team->work_shares[0];
    190  1.1.1.9  mrg   gomp_init_work_share (&team->work_shares[0], 0, nthreads);
    191      1.1  mrg   team->work_shares[0].next_alloc = NULL;
    192      1.1  mrg   team->work_share_list_free = NULL;
    193      1.1  mrg   team->work_share_list_alloc = &team->work_shares[1];
    194      1.1  mrg   for (i = 1; i < 7; i++)
    195      1.1  mrg     team->work_shares[i].next_free = &team->work_shares[i + 1];
    196      1.1  mrg   team->work_shares[i].next_free = NULL;
    197      1.1  mrg 
    198      1.1  mrg   gomp_sem_init (&team->master_release, 0);
    199      1.1  mrg   team->ordered_release = (void *) &team->implicit_task[nthreads];
    200      1.1  mrg   team->ordered_release[0] = &team->master_release;
    201      1.1  mrg 
    202  1.1.1.4  mrg   priority_queue_init (&team->task_queue);
    203      1.1  mrg   team->task_count = 0;
    204  1.1.1.3  mrg   team->task_queued_count = 0;
    205      1.1  mrg   team->task_running_count = 0;
    206  1.1.1.3  mrg   team->work_share_cancelled = 0;
    207  1.1.1.3  mrg   team->team_cancelled = 0;
    208      1.1  mrg 
    209      1.1  mrg   return team;
    210      1.1  mrg }
    211      1.1  mrg 
    212      1.1  mrg 
    213      1.1  mrg /* Free a team data structure.  */
    214      1.1  mrg 
    215      1.1  mrg static void
    216      1.1  mrg free_team (struct gomp_team *team)
    217      1.1  mrg {
    218  1.1.1.4  mrg #ifndef HAVE_SYNC_BUILTINS
    219  1.1.1.4  mrg   gomp_mutex_destroy (&team->work_share_list_free_lock);
    220  1.1.1.4  mrg #endif
    221      1.1  mrg   gomp_barrier_destroy (&team->barrier);
    222      1.1  mrg   gomp_mutex_destroy (&team->task_lock);
    223  1.1.1.4  mrg   priority_queue_free (&team->task_queue);
    224      1.1  mrg   free (team);
    225      1.1  mrg }
    226      1.1  mrg 
    227      1.1  mrg static void
    228      1.1  mrg gomp_free_pool_helper (void *thread_pool)
    229      1.1  mrg {
    230  1.1.1.3  mrg   struct gomp_thread *thr = gomp_thread ();
    231      1.1  mrg   struct gomp_thread_pool *pool
    232      1.1  mrg     = (struct gomp_thread_pool *) thread_pool;
    233  1.1.1.5  mrg   gomp_simple_barrier_wait_last (&pool->threads_dock);
    234  1.1.1.3  mrg   gomp_sem_destroy (&thr->release);
    235  1.1.1.3  mrg   thr->thread_pool = NULL;
    236  1.1.1.3  mrg   thr->task = NULL;
    237  1.1.1.5  mrg #ifdef LIBGOMP_USE_PTHREADS
    238  1.1.1.9  mrg   pthread_detach (pthread_self ());
    239      1.1  mrg   pthread_exit (NULL);
    240  1.1.1.5  mrg #elif defined(__nvptx__)
    241  1.1.1.5  mrg   asm ("exit;");
    242  1.1.1.5  mrg #else
    243  1.1.1.5  mrg #error gomp_free_pool_helper must terminate the thread
    244  1.1.1.5  mrg #endif
    245      1.1  mrg }
    246      1.1  mrg 
    247      1.1  mrg /* Free a thread pool and release its threads. */
    248      1.1  mrg 
    249  1.1.1.3  mrg void
    250      1.1  mrg gomp_free_thread (void *arg __attribute__((unused)))
    251      1.1  mrg {
    252      1.1  mrg   struct gomp_thread *thr = gomp_thread ();
    253      1.1  mrg   struct gomp_thread_pool *pool = thr->thread_pool;
    254      1.1  mrg   if (pool)
    255      1.1  mrg     {
    256      1.1  mrg       if (pool->threads_used > 0)
    257      1.1  mrg 	{
    258      1.1  mrg 	  int i;
    259      1.1  mrg 	  for (i = 1; i < pool->threads_used; i++)
    260      1.1  mrg 	    {
    261      1.1  mrg 	      struct gomp_thread *nthr = pool->threads[i];
    262      1.1  mrg 	      nthr->fn = gomp_free_pool_helper;
    263      1.1  mrg 	      nthr->data = pool;
    264      1.1  mrg 	    }
    265      1.1  mrg 	  /* This barrier undocks threads docked on pool->threads_dock.  */
    266  1.1.1.5  mrg 	  gomp_simple_barrier_wait (&pool->threads_dock);
    267      1.1  mrg 	  /* And this waits till all threads have called gomp_barrier_wait_last
    268      1.1  mrg 	     in gomp_free_pool_helper.  */
    269  1.1.1.5  mrg 	  gomp_simple_barrier_wait (&pool->threads_dock);
    270      1.1  mrg 	  /* Now it is safe to destroy the barrier and free the pool.  */
    271  1.1.1.5  mrg 	  gomp_simple_barrier_destroy (&pool->threads_dock);
    272  1.1.1.2  mrg 
    273  1.1.1.2  mrg #ifdef HAVE_SYNC_BUILTINS
    274  1.1.1.2  mrg 	  __sync_fetch_and_add (&gomp_managed_threads,
    275  1.1.1.2  mrg 				1L - pool->threads_used);
    276  1.1.1.2  mrg #else
    277  1.1.1.3  mrg 	  gomp_mutex_lock (&gomp_managed_threads_lock);
    278  1.1.1.2  mrg 	  gomp_managed_threads -= pool->threads_used - 1L;
    279  1.1.1.3  mrg 	  gomp_mutex_unlock (&gomp_managed_threads_lock);
    280  1.1.1.2  mrg #endif
    281      1.1  mrg 	}
    282      1.1  mrg       if (pool->last_team)
    283      1.1  mrg 	free_team (pool->last_team);
    284  1.1.1.5  mrg #ifndef __nvptx__
    285  1.1.1.5  mrg       free (pool->threads);
    286      1.1  mrg       free (pool);
    287  1.1.1.5  mrg #endif
    288      1.1  mrg       thr->thread_pool = NULL;
    289      1.1  mrg     }
    290  1.1.1.4  mrg   if (thr->ts.level == 0 && __builtin_expect (thr->ts.team != NULL, 0))
    291  1.1.1.4  mrg     gomp_team_end ();
    292      1.1  mrg   if (thr->task != NULL)
    293      1.1  mrg     {
    294      1.1  mrg       struct gomp_task *task = thr->task;
    295      1.1  mrg       gomp_end_task ();
    296      1.1  mrg       free (task);
    297      1.1  mrg     }
    298      1.1  mrg }
    299      1.1  mrg 
    300      1.1  mrg /* Launch a team.  */
    301      1.1  mrg 
    302  1.1.1.5  mrg #ifdef LIBGOMP_USE_PTHREADS
    303      1.1  mrg void
    304      1.1  mrg gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
    305  1.1.1.9  mrg 		 unsigned flags, struct gomp_team *team,
    306  1.1.1.9  mrg 		 struct gomp_taskgroup *taskgroup)
    307      1.1  mrg {
    308      1.1  mrg   struct gomp_thread_start_data *start_data;
    309      1.1  mrg   struct gomp_thread *thr, *nthr;
    310      1.1  mrg   struct gomp_task *task;
    311      1.1  mrg   struct gomp_task_icv *icv;
    312      1.1  mrg   bool nested;
    313      1.1  mrg   struct gomp_thread_pool *pool;
    314      1.1  mrg   unsigned i, n, old_threads_used = 0;
    315      1.1  mrg   pthread_attr_t thread_attr, *attr;
    316  1.1.1.2  mrg   unsigned long nthreads_var;
    317  1.1.1.3  mrg   char bind, bind_var;
    318  1.1.1.3  mrg   unsigned int s = 0, rest = 0, p = 0, k = 0;
    319  1.1.1.3  mrg   unsigned int affinity_count = 0;
    320  1.1.1.3  mrg   struct gomp_thread **affinity_thr = NULL;
    321  1.1.1.9  mrg   bool force_display = false;
    322      1.1  mrg 
    323      1.1  mrg   thr = gomp_thread ();
    324  1.1.1.4  mrg   nested = thr->ts.level;
    325      1.1  mrg   pool = thr->thread_pool;
    326      1.1  mrg   task = thr->task;
    327      1.1  mrg   icv = task ? &task->icv : &gomp_global_icv;
    328  1.1.1.3  mrg   if (__builtin_expect (gomp_places_list != NULL, 0) && thr->place == 0)
    329  1.1.1.9  mrg     {
    330  1.1.1.9  mrg       gomp_init_affinity ();
    331  1.1.1.9  mrg       if (__builtin_expect (gomp_display_affinity_var, 0) && nthreads == 1)
    332  1.1.1.9  mrg 	gomp_display_affinity_thread (gomp_thread_self (), &thr->ts,
    333  1.1.1.9  mrg 				      thr->place);
    334  1.1.1.9  mrg     }
    335      1.1  mrg 
    336      1.1  mrg   /* Always save the previous state, even if this isn't a nested team.
    337      1.1  mrg      In particular, we should save any work share state from an outer
    338      1.1  mrg      orphaned work share construct.  */
    339      1.1  mrg   team->prev_ts = thr->ts;
    340      1.1  mrg 
    341      1.1  mrg   thr->ts.team = team;
    342      1.1  mrg   thr->ts.team_id = 0;
    343      1.1  mrg   ++thr->ts.level;
    344      1.1  mrg   if (nthreads > 1)
    345      1.1  mrg     ++thr->ts.active_level;
    346      1.1  mrg   thr->ts.work_share = &team->work_shares[0];
    347      1.1  mrg   thr->ts.last_work_share = NULL;
    348      1.1  mrg #ifdef HAVE_SYNC_BUILTINS
    349      1.1  mrg   thr->ts.single_count = 0;
    350      1.1  mrg #endif
    351      1.1  mrg   thr->ts.static_trip = 0;
    352      1.1  mrg   thr->task = &team->implicit_task[0];
    353  1.1.1.9  mrg #ifdef GOMP_NEEDS_THREAD_HANDLE
    354  1.1.1.9  mrg   thr->handle = pthread_self ();
    355  1.1.1.9  mrg #endif
    356  1.1.1.2  mrg   nthreads_var = icv->nthreads_var;
    357  1.1.1.2  mrg   if (__builtin_expect (gomp_nthreads_var_list != NULL, 0)
    358  1.1.1.2  mrg       && thr->ts.level < gomp_nthreads_var_list_len)
    359  1.1.1.2  mrg     nthreads_var = gomp_nthreads_var_list[thr->ts.level];
    360  1.1.1.3  mrg   bind_var = icv->bind_var;
    361  1.1.1.3  mrg   if (bind_var != omp_proc_bind_false && (flags & 7) != omp_proc_bind_false)
    362  1.1.1.3  mrg     bind_var = flags & 7;
    363  1.1.1.3  mrg   bind = bind_var;
    364  1.1.1.3  mrg   if (__builtin_expect (gomp_bind_var_list != NULL, 0)
    365  1.1.1.3  mrg       && thr->ts.level < gomp_bind_var_list_len)
    366  1.1.1.3  mrg     bind_var = gomp_bind_var_list[thr->ts.level];
    367      1.1  mrg   gomp_init_task (thr->task, task, icv);
    368  1.1.1.9  mrg   thr->task->taskgroup = taskgroup;
    369  1.1.1.2  mrg   team->implicit_task[0].icv.nthreads_var = nthreads_var;
    370  1.1.1.3  mrg   team->implicit_task[0].icv.bind_var = bind_var;
    371      1.1  mrg 
    372      1.1  mrg   if (nthreads == 1)
    373      1.1  mrg     return;
    374      1.1  mrg 
    375      1.1  mrg   i = 1;
    376      1.1  mrg 
    377  1.1.1.3  mrg   if (__builtin_expect (gomp_places_list != NULL, 0))
    378  1.1.1.3  mrg     {
    379  1.1.1.3  mrg       /* Depending on chosen proc_bind model, set subpartition
    380  1.1.1.3  mrg 	 for the master thread and initialize helper variables
    381  1.1.1.3  mrg 	 P and optionally S, K and/or REST used by later place
    382  1.1.1.3  mrg 	 computation for each additional thread.  */
    383  1.1.1.3  mrg       p = thr->place - 1;
    384  1.1.1.3  mrg       switch (bind)
    385  1.1.1.3  mrg 	{
    386  1.1.1.3  mrg 	case omp_proc_bind_true:
    387  1.1.1.3  mrg 	case omp_proc_bind_close:
    388  1.1.1.3  mrg 	  if (nthreads > thr->ts.place_partition_len)
    389  1.1.1.3  mrg 	    {
    390  1.1.1.3  mrg 	      /* T > P.  S threads will be placed in each place,
    391  1.1.1.3  mrg 		 and the final REM threads placed one by one
    392  1.1.1.3  mrg 		 into the already occupied places.  */
    393  1.1.1.3  mrg 	      s = nthreads / thr->ts.place_partition_len;
    394  1.1.1.3  mrg 	      rest = nthreads % thr->ts.place_partition_len;
    395  1.1.1.3  mrg 	    }
    396  1.1.1.3  mrg 	  else
    397  1.1.1.3  mrg 	    s = 1;
    398  1.1.1.3  mrg 	  k = 1;
    399  1.1.1.3  mrg 	  break;
    400  1.1.1.3  mrg 	case omp_proc_bind_master:
    401  1.1.1.3  mrg 	  /* Each thread will be bound to master's place.  */
    402  1.1.1.3  mrg 	  break;
    403  1.1.1.3  mrg 	case omp_proc_bind_spread:
    404  1.1.1.3  mrg 	  if (nthreads <= thr->ts.place_partition_len)
    405  1.1.1.3  mrg 	    {
    406  1.1.1.3  mrg 	      /* T <= P.  Each subpartition will have in between s
    407  1.1.1.3  mrg 		 and s+1 places (subpartitions starting at or
    408  1.1.1.3  mrg 		 after rest will have s places, earlier s+1 places),
    409  1.1.1.3  mrg 		 each thread will be bound to the first place in
    410  1.1.1.3  mrg 		 its subpartition (except for the master thread
    411  1.1.1.3  mrg 		 that can be bound to another place in its
    412  1.1.1.3  mrg 		 subpartition).  */
    413  1.1.1.3  mrg 	      s = thr->ts.place_partition_len / nthreads;
    414  1.1.1.3  mrg 	      rest = thr->ts.place_partition_len % nthreads;
    415  1.1.1.3  mrg 	      rest = (s + 1) * rest + thr->ts.place_partition_off;
    416  1.1.1.3  mrg 	      if (p < rest)
    417  1.1.1.3  mrg 		{
    418  1.1.1.3  mrg 		  p -= (p - thr->ts.place_partition_off) % (s + 1);
    419  1.1.1.3  mrg 		  thr->ts.place_partition_len = s + 1;
    420  1.1.1.3  mrg 		}
    421  1.1.1.3  mrg 	      else
    422  1.1.1.3  mrg 		{
    423  1.1.1.3  mrg 		  p -= (p - rest) % s;
    424  1.1.1.3  mrg 		  thr->ts.place_partition_len = s;
    425  1.1.1.3  mrg 		}
    426  1.1.1.3  mrg 	      thr->ts.place_partition_off = p;
    427  1.1.1.3  mrg 	    }
    428  1.1.1.3  mrg 	  else
    429  1.1.1.3  mrg 	    {
    430  1.1.1.3  mrg 	      /* T > P.  Each subpartition will have just a single
    431  1.1.1.3  mrg 		 place and we'll place between s and s+1
    432  1.1.1.3  mrg 		 threads into each subpartition.  */
    433  1.1.1.3  mrg 	      s = nthreads / thr->ts.place_partition_len;
    434  1.1.1.3  mrg 	      rest = nthreads % thr->ts.place_partition_len;
    435  1.1.1.3  mrg 	      thr->ts.place_partition_off = p;
    436  1.1.1.3  mrg 	      thr->ts.place_partition_len = 1;
    437  1.1.1.3  mrg 	      k = 1;
    438  1.1.1.3  mrg 	    }
    439  1.1.1.3  mrg 	  break;
    440  1.1.1.3  mrg 	}
    441  1.1.1.3  mrg     }
    442  1.1.1.3  mrg   else
    443  1.1.1.3  mrg     bind = omp_proc_bind_false;
    444  1.1.1.3  mrg 
    445      1.1  mrg   /* We only allow the reuse of idle threads for non-nested PARALLEL
    446      1.1  mrg      regions.  This appears to be implied by the semantics of
    447      1.1  mrg      threadprivate variables, but perhaps that's reading too much into
    448      1.1  mrg      things.  Certainly it does prevent any locking problems, since
    449      1.1  mrg      only the initial program thread will modify gomp_threads.  */
    450      1.1  mrg   if (!nested)
    451      1.1  mrg     {
    452      1.1  mrg       old_threads_used = pool->threads_used;
    453      1.1  mrg 
    454      1.1  mrg       if (nthreads <= old_threads_used)
    455      1.1  mrg 	n = nthreads;
    456      1.1  mrg       else if (old_threads_used == 0)
    457      1.1  mrg 	{
    458      1.1  mrg 	  n = 0;
    459  1.1.1.5  mrg 	  gomp_simple_barrier_init (&pool->threads_dock, nthreads);
    460      1.1  mrg 	}
    461      1.1  mrg       else
    462      1.1  mrg 	{
    463      1.1  mrg 	  n = old_threads_used;
    464      1.1  mrg 
    465      1.1  mrg 	  /* Increase the barrier threshold to make sure all new
    466      1.1  mrg 	     threads arrive before the team is released.  */
    467  1.1.1.5  mrg 	  gomp_simple_barrier_reinit (&pool->threads_dock, nthreads);
    468      1.1  mrg 	}
    469      1.1  mrg 
    470      1.1  mrg       /* Not true yet, but soon will be.  We're going to release all
    471      1.1  mrg 	 threads from the dock, and those that aren't part of the
    472      1.1  mrg 	 team will exit.  */
    473      1.1  mrg       pool->threads_used = nthreads;
    474      1.1  mrg 
    475  1.1.1.3  mrg       /* If necessary, expand the size of the gomp_threads array.  It is
    476  1.1.1.3  mrg 	 expected that changes in the number of threads are rare, thus we
    477  1.1.1.3  mrg 	 make no effort to expand gomp_threads_size geometrically.  */
    478  1.1.1.3  mrg       if (nthreads >= pool->threads_size)
    479  1.1.1.3  mrg 	{
    480  1.1.1.3  mrg 	  pool->threads_size = nthreads + 1;
    481  1.1.1.3  mrg 	  pool->threads
    482  1.1.1.3  mrg 	    = gomp_realloc (pool->threads,
    483  1.1.1.3  mrg 			    pool->threads_size
    484  1.1.1.9  mrg 			    * sizeof (struct gomp_thread *));
    485  1.1.1.9  mrg 	  /* Add current (master) thread to threads[].  */
    486  1.1.1.9  mrg 	  pool->threads[0] = thr;
    487  1.1.1.3  mrg 	}
    488  1.1.1.3  mrg 
    489      1.1  mrg       /* Release existing idle threads.  */
    490      1.1  mrg       for (; i < n; ++i)
    491      1.1  mrg 	{
    492  1.1.1.3  mrg 	  unsigned int place_partition_off = thr->ts.place_partition_off;
    493  1.1.1.3  mrg 	  unsigned int place_partition_len = thr->ts.place_partition_len;
    494  1.1.1.3  mrg 	  unsigned int place = 0;
    495  1.1.1.3  mrg 	  if (__builtin_expect (gomp_places_list != NULL, 0))
    496  1.1.1.3  mrg 	    {
    497  1.1.1.3  mrg 	      switch (bind)
    498  1.1.1.3  mrg 		{
    499  1.1.1.3  mrg 		case omp_proc_bind_true:
    500  1.1.1.3  mrg 		case omp_proc_bind_close:
    501  1.1.1.3  mrg 		  if (k == s)
    502  1.1.1.3  mrg 		    {
    503  1.1.1.3  mrg 		      ++p;
    504  1.1.1.3  mrg 		      if (p == (team->prev_ts.place_partition_off
    505  1.1.1.3  mrg 				+ team->prev_ts.place_partition_len))
    506  1.1.1.3  mrg 			p = team->prev_ts.place_partition_off;
    507  1.1.1.3  mrg 		      k = 1;
    508  1.1.1.3  mrg 		      if (i == nthreads - rest)
    509  1.1.1.3  mrg 			s = 1;
    510  1.1.1.3  mrg 		    }
    511  1.1.1.3  mrg 		  else
    512  1.1.1.3  mrg 		    ++k;
    513  1.1.1.3  mrg 		  break;
    514  1.1.1.3  mrg 		case omp_proc_bind_master:
    515  1.1.1.3  mrg 		  break;
    516  1.1.1.3  mrg 		case omp_proc_bind_spread:
    517  1.1.1.3  mrg 		  if (k == 0)
    518  1.1.1.3  mrg 		    {
    519  1.1.1.3  mrg 		      /* T <= P.  */
    520  1.1.1.3  mrg 		      if (p < rest)
    521  1.1.1.3  mrg 			p += s + 1;
    522  1.1.1.3  mrg 		      else
    523  1.1.1.3  mrg 			p += s;
    524  1.1.1.3  mrg 		      if (p == (team->prev_ts.place_partition_off
    525  1.1.1.3  mrg 				+ team->prev_ts.place_partition_len))
    526  1.1.1.3  mrg 			p = team->prev_ts.place_partition_off;
    527  1.1.1.3  mrg 		      place_partition_off = p;
    528  1.1.1.3  mrg 		      if (p < rest)
    529  1.1.1.3  mrg 			place_partition_len = s + 1;
    530  1.1.1.3  mrg 		      else
    531  1.1.1.3  mrg 			place_partition_len = s;
    532  1.1.1.3  mrg 		    }
    533  1.1.1.3  mrg 		  else
    534  1.1.1.3  mrg 		    {
    535  1.1.1.3  mrg 		      /* T > P.  */
    536  1.1.1.3  mrg 		      if (k == s)
    537  1.1.1.3  mrg 			{
    538  1.1.1.3  mrg 			  ++p;
    539  1.1.1.3  mrg 			  if (p == (team->prev_ts.place_partition_off
    540  1.1.1.3  mrg 				    + team->prev_ts.place_partition_len))
    541  1.1.1.3  mrg 			    p = team->prev_ts.place_partition_off;
    542  1.1.1.3  mrg 			  k = 1;
    543  1.1.1.3  mrg 			  if (i == nthreads - rest)
    544  1.1.1.3  mrg 			    s = 1;
    545  1.1.1.3  mrg 			}
    546  1.1.1.3  mrg 		      else
    547  1.1.1.3  mrg 			++k;
    548  1.1.1.3  mrg 		      place_partition_off = p;
    549  1.1.1.3  mrg 		      place_partition_len = 1;
    550  1.1.1.3  mrg 		    }
    551  1.1.1.3  mrg 		  break;
    552  1.1.1.3  mrg 		}
    553  1.1.1.3  mrg 	      if (affinity_thr != NULL
    554  1.1.1.3  mrg 		  || (bind != omp_proc_bind_true
    555  1.1.1.3  mrg 		      && pool->threads[i]->place != p + 1)
    556  1.1.1.3  mrg 		  || pool->threads[i]->place <= place_partition_off
    557  1.1.1.3  mrg 		  || pool->threads[i]->place > (place_partition_off
    558  1.1.1.3  mrg 						+ place_partition_len))
    559  1.1.1.3  mrg 		{
    560  1.1.1.3  mrg 		  unsigned int l;
    561  1.1.1.9  mrg 		  force_display = true;
    562  1.1.1.3  mrg 		  if (affinity_thr == NULL)
    563  1.1.1.3  mrg 		    {
    564  1.1.1.3  mrg 		      unsigned int j;
    565  1.1.1.3  mrg 
    566  1.1.1.3  mrg 		      if (team->prev_ts.place_partition_len > 64)
    567  1.1.1.3  mrg 			affinity_thr
    568  1.1.1.3  mrg 			  = gomp_malloc (team->prev_ts.place_partition_len
    569  1.1.1.3  mrg 					 * sizeof (struct gomp_thread *));
    570  1.1.1.3  mrg 		      else
    571  1.1.1.3  mrg 			affinity_thr
    572  1.1.1.3  mrg 			  = gomp_alloca (team->prev_ts.place_partition_len
    573  1.1.1.3  mrg 					 * sizeof (struct gomp_thread *));
    574  1.1.1.3  mrg 		      memset (affinity_thr, '\0',
    575  1.1.1.3  mrg 			      team->prev_ts.place_partition_len
    576  1.1.1.3  mrg 			      * sizeof (struct gomp_thread *));
    577  1.1.1.3  mrg 		      for (j = i; j < old_threads_used; j++)
    578  1.1.1.3  mrg 			{
    579  1.1.1.3  mrg 			  if (pool->threads[j]->place
    580  1.1.1.3  mrg 			      > team->prev_ts.place_partition_off
    581  1.1.1.3  mrg 			      && (pool->threads[j]->place
    582  1.1.1.3  mrg 				  <= (team->prev_ts.place_partition_off
    583  1.1.1.3  mrg 				      + team->prev_ts.place_partition_len)))
    584  1.1.1.3  mrg 			    {
    585  1.1.1.3  mrg 			      l = pool->threads[j]->place - 1
    586  1.1.1.3  mrg 				  - team->prev_ts.place_partition_off;
    587  1.1.1.3  mrg 			      pool->threads[j]->data = affinity_thr[l];
    588  1.1.1.3  mrg 			      affinity_thr[l] = pool->threads[j];
    589  1.1.1.3  mrg 			    }
    590  1.1.1.3  mrg 			  pool->threads[j] = NULL;
    591  1.1.1.3  mrg 			}
    592  1.1.1.3  mrg 		      if (nthreads > old_threads_used)
    593  1.1.1.3  mrg 			memset (&pool->threads[old_threads_used],
    594  1.1.1.3  mrg 				'\0', ((nthreads - old_threads_used)
    595  1.1.1.3  mrg 				       * sizeof (struct gomp_thread *)));
    596  1.1.1.3  mrg 		      n = nthreads;
    597  1.1.1.3  mrg 		      affinity_count = old_threads_used - i;
    598  1.1.1.3  mrg 		    }
    599  1.1.1.3  mrg 		  if (affinity_count == 0)
    600  1.1.1.3  mrg 		    break;
    601  1.1.1.3  mrg 		  l = p;
    602  1.1.1.3  mrg 		  if (affinity_thr[l - team->prev_ts.place_partition_off]
    603  1.1.1.3  mrg 		      == NULL)
    604  1.1.1.3  mrg 		    {
    605  1.1.1.3  mrg 		      if (bind != omp_proc_bind_true)
    606  1.1.1.3  mrg 			continue;
    607  1.1.1.3  mrg 		      for (l = place_partition_off;
    608  1.1.1.3  mrg 			   l < place_partition_off + place_partition_len;
    609  1.1.1.3  mrg 			   l++)
    610  1.1.1.3  mrg 			if (affinity_thr[l - team->prev_ts.place_partition_off]
    611  1.1.1.3  mrg 			    != NULL)
    612  1.1.1.3  mrg 			  break;
    613  1.1.1.3  mrg 		      if (l == place_partition_off + place_partition_len)
    614  1.1.1.3  mrg 			continue;
    615  1.1.1.3  mrg 		    }
    616  1.1.1.3  mrg 		  nthr = affinity_thr[l - team->prev_ts.place_partition_off];
    617  1.1.1.3  mrg 		  affinity_thr[l - team->prev_ts.place_partition_off]
    618  1.1.1.3  mrg 		    = (struct gomp_thread *) nthr->data;
    619  1.1.1.3  mrg 		  affinity_count--;
    620  1.1.1.3  mrg 		  pool->threads[i] = nthr;
    621  1.1.1.3  mrg 		}
    622  1.1.1.3  mrg 	      else
    623  1.1.1.3  mrg 		nthr = pool->threads[i];
    624  1.1.1.3  mrg 	      place = p + 1;
    625  1.1.1.3  mrg 	    }
    626  1.1.1.3  mrg 	  else
    627  1.1.1.3  mrg 	    nthr = pool->threads[i];
    628      1.1  mrg 	  nthr->ts.team = team;
    629      1.1  mrg 	  nthr->ts.work_share = &team->work_shares[0];
    630      1.1  mrg 	  nthr->ts.last_work_share = NULL;
    631      1.1  mrg 	  nthr->ts.team_id = i;
    632      1.1  mrg 	  nthr->ts.level = team->prev_ts.level + 1;
    633      1.1  mrg 	  nthr->ts.active_level = thr->ts.active_level;
    634  1.1.1.3  mrg 	  nthr->ts.place_partition_off = place_partition_off;
    635  1.1.1.3  mrg 	  nthr->ts.place_partition_len = place_partition_len;
    636      1.1  mrg #ifdef HAVE_SYNC_BUILTINS
    637      1.1  mrg 	  nthr->ts.single_count = 0;
    638      1.1  mrg #endif
    639      1.1  mrg 	  nthr->ts.static_trip = 0;
    640      1.1  mrg 	  nthr->task = &team->implicit_task[i];
    641  1.1.1.3  mrg 	  nthr->place = place;
    642      1.1  mrg 	  gomp_init_task (nthr->task, task, icv);
    643  1.1.1.2  mrg 	  team->implicit_task[i].icv.nthreads_var = nthreads_var;
    644  1.1.1.3  mrg 	  team->implicit_task[i].icv.bind_var = bind_var;
    645  1.1.1.9  mrg 	  nthr->task->taskgroup = taskgroup;
    646      1.1  mrg 	  nthr->fn = fn;
    647      1.1  mrg 	  nthr->data = data;
    648      1.1  mrg 	  team->ordered_release[i] = &nthr->release;
    649      1.1  mrg 	}
    650      1.1  mrg 
    651  1.1.1.3  mrg       if (__builtin_expect (affinity_thr != NULL, 0))
    652  1.1.1.3  mrg 	{
    653  1.1.1.3  mrg 	  /* If AFFINITY_THR is non-NULL just because we had to
    654  1.1.1.3  mrg 	     permute some threads in the pool, but we've managed
    655  1.1.1.3  mrg 	     to find exactly as many old threads as we'd find
    656  1.1.1.3  mrg 	     without affinity, we don't need to handle this
    657  1.1.1.3  mrg 	     specially anymore.  */
    658  1.1.1.3  mrg 	  if (nthreads <= old_threads_used
    659  1.1.1.3  mrg 	      ? (affinity_count == old_threads_used - nthreads)
    660  1.1.1.3  mrg 	      : (i == old_threads_used))
    661  1.1.1.3  mrg 	    {
    662  1.1.1.3  mrg 	      if (team->prev_ts.place_partition_len > 64)
    663  1.1.1.3  mrg 		free (affinity_thr);
    664  1.1.1.3  mrg 	      affinity_thr = NULL;
    665  1.1.1.3  mrg 	      affinity_count = 0;
    666  1.1.1.3  mrg 	    }
    667  1.1.1.3  mrg 	  else
    668  1.1.1.3  mrg 	    {
    669  1.1.1.3  mrg 	      i = 1;
    670  1.1.1.3  mrg 	      /* We are going to compute the places/subpartitions
    671  1.1.1.3  mrg 		 again from the beginning.  So, we need to reinitialize
    672  1.1.1.3  mrg 		 vars modified by the switch (bind) above inside
    673  1.1.1.3  mrg 		 of the loop, to the state they had after the initial
    674  1.1.1.3  mrg 		 switch (bind).  */
    675  1.1.1.3  mrg 	      switch (bind)
    676  1.1.1.3  mrg 		{
    677  1.1.1.3  mrg 		case omp_proc_bind_true:
    678  1.1.1.3  mrg 		case omp_proc_bind_close:
    679  1.1.1.3  mrg 		  if (nthreads > thr->ts.place_partition_len)
    680  1.1.1.3  mrg 		    /* T > P.  S has been changed, so needs
    681  1.1.1.3  mrg 		       to be recomputed.  */
    682  1.1.1.3  mrg 		    s = nthreads / thr->ts.place_partition_len;
    683  1.1.1.3  mrg 		  k = 1;
    684  1.1.1.3  mrg 		  p = thr->place - 1;
    685  1.1.1.3  mrg 		  break;
    686  1.1.1.3  mrg 		case omp_proc_bind_master:
    687  1.1.1.3  mrg 		  /* No vars have been changed.  */
    688  1.1.1.3  mrg 		  break;
    689  1.1.1.3  mrg 		case omp_proc_bind_spread:
    690  1.1.1.3  mrg 		  p = thr->ts.place_partition_off;
    691  1.1.1.3  mrg 		  if (k != 0)
    692  1.1.1.3  mrg 		    {
    693  1.1.1.3  mrg 		      /* T > P.  */
    694  1.1.1.3  mrg 		      s = nthreads / team->prev_ts.place_partition_len;
    695  1.1.1.3  mrg 		      k = 1;
    696  1.1.1.3  mrg 		    }
    697  1.1.1.3  mrg 		  break;
    698  1.1.1.3  mrg 		}
    699  1.1.1.3  mrg 
    700  1.1.1.3  mrg 	      /* Increase the barrier threshold to make sure all new
    701  1.1.1.3  mrg 		 threads and all the threads we're going to let die
    702  1.1.1.3  mrg 		 arrive before the team is released.  */
    703  1.1.1.3  mrg 	      if (affinity_count)
    704  1.1.1.5  mrg 		gomp_simple_barrier_reinit (&pool->threads_dock,
    705  1.1.1.5  mrg 					    nthreads + affinity_count);
    706  1.1.1.3  mrg 	    }
    707  1.1.1.3  mrg 	}
    708  1.1.1.3  mrg 
    709      1.1  mrg       if (i == nthreads)
    710      1.1  mrg 	goto do_release;
    711      1.1  mrg 
    712      1.1  mrg     }
    713      1.1  mrg 
    714  1.1.1.3  mrg   if (__builtin_expect (nthreads + affinity_count > old_threads_used, 0))
    715      1.1  mrg     {
    716  1.1.1.3  mrg       long diff = (long) (nthreads + affinity_count) - (long) old_threads_used;
    717      1.1  mrg 
    718      1.1  mrg       if (old_threads_used == 0)
    719      1.1  mrg 	--diff;
    720      1.1  mrg 
    721      1.1  mrg #ifdef HAVE_SYNC_BUILTINS
    722      1.1  mrg       __sync_fetch_and_add (&gomp_managed_threads, diff);
    723      1.1  mrg #else
    724  1.1.1.3  mrg       gomp_mutex_lock (&gomp_managed_threads_lock);
    725      1.1  mrg       gomp_managed_threads += diff;
    726  1.1.1.3  mrg       gomp_mutex_unlock (&gomp_managed_threads_lock);
    727      1.1  mrg #endif
    728      1.1  mrg     }
    729      1.1  mrg 
    730      1.1  mrg   attr = &gomp_thread_attr;
    731  1.1.1.3  mrg   if (__builtin_expect (gomp_places_list != NULL, 0))
    732      1.1  mrg     {
    733      1.1  mrg       size_t stacksize;
    734      1.1  mrg       pthread_attr_init (&thread_attr);
    735      1.1  mrg       if (! pthread_attr_getstacksize (&gomp_thread_attr, &stacksize))
    736      1.1  mrg 	pthread_attr_setstacksize (&thread_attr, stacksize);
    737      1.1  mrg       attr = &thread_attr;
    738      1.1  mrg     }
    739      1.1  mrg 
    740      1.1  mrg   start_data = gomp_alloca (sizeof (struct gomp_thread_start_data)
    741  1.1.1.9  mrg 			    * (nthreads - i));
    742      1.1  mrg 
    743      1.1  mrg   /* Launch new threads.  */
    744  1.1.1.3  mrg   for (; i < nthreads; ++i)
    745      1.1  mrg     {
    746      1.1  mrg       int err;
    747      1.1  mrg 
    748  1.1.1.3  mrg       start_data->ts.place_partition_off = thr->ts.place_partition_off;
    749  1.1.1.3  mrg       start_data->ts.place_partition_len = thr->ts.place_partition_len;
    750  1.1.1.3  mrg       start_data->place = 0;
    751  1.1.1.3  mrg       if (__builtin_expect (gomp_places_list != NULL, 0))
    752  1.1.1.3  mrg 	{
    753  1.1.1.3  mrg 	  switch (bind)
    754  1.1.1.3  mrg 	    {
    755  1.1.1.3  mrg 	    case omp_proc_bind_true:
    756  1.1.1.3  mrg 	    case omp_proc_bind_close:
    757  1.1.1.3  mrg 	      if (k == s)
    758  1.1.1.3  mrg 		{
    759  1.1.1.3  mrg 		  ++p;
    760  1.1.1.3  mrg 		  if (p == (team->prev_ts.place_partition_off
    761  1.1.1.3  mrg 			    + team->prev_ts.place_partition_len))
    762  1.1.1.3  mrg 		    p = team->prev_ts.place_partition_off;
    763  1.1.1.3  mrg 		  k = 1;
    764  1.1.1.3  mrg 		  if (i == nthreads - rest)
    765  1.1.1.3  mrg 		    s = 1;
    766  1.1.1.3  mrg 		}
    767  1.1.1.3  mrg 	      else
    768  1.1.1.3  mrg 		++k;
    769  1.1.1.3  mrg 	      break;
    770  1.1.1.3  mrg 	    case omp_proc_bind_master:
    771  1.1.1.3  mrg 	      break;
    772  1.1.1.3  mrg 	    case omp_proc_bind_spread:
    773  1.1.1.3  mrg 	      if (k == 0)
    774  1.1.1.3  mrg 		{
    775  1.1.1.3  mrg 		  /* T <= P.  */
    776  1.1.1.3  mrg 		  if (p < rest)
    777  1.1.1.3  mrg 		    p += s + 1;
    778  1.1.1.3  mrg 		  else
    779  1.1.1.3  mrg 		    p += s;
    780  1.1.1.3  mrg 		  if (p == (team->prev_ts.place_partition_off
    781  1.1.1.3  mrg 			    + team->prev_ts.place_partition_len))
    782  1.1.1.3  mrg 		    p = team->prev_ts.place_partition_off;
    783  1.1.1.3  mrg 		  start_data->ts.place_partition_off = p;
    784  1.1.1.3  mrg 		  if (p < rest)
    785  1.1.1.3  mrg 		    start_data->ts.place_partition_len = s + 1;
    786  1.1.1.3  mrg 		  else
    787  1.1.1.3  mrg 		    start_data->ts.place_partition_len = s;
    788  1.1.1.3  mrg 		}
    789  1.1.1.3  mrg 	      else
    790  1.1.1.3  mrg 		{
    791  1.1.1.3  mrg 		  /* T > P.  */
    792  1.1.1.3  mrg 		  if (k == s)
    793  1.1.1.3  mrg 		    {
    794  1.1.1.3  mrg 		      ++p;
    795  1.1.1.3  mrg 		      if (p == (team->prev_ts.place_partition_off
    796  1.1.1.3  mrg 				+ team->prev_ts.place_partition_len))
    797  1.1.1.3  mrg 			p = team->prev_ts.place_partition_off;
    798  1.1.1.3  mrg 		      k = 1;
    799  1.1.1.3  mrg 		      if (i == nthreads - rest)
    800  1.1.1.3  mrg 			s = 1;
    801  1.1.1.3  mrg 		    }
    802  1.1.1.3  mrg 		  else
    803  1.1.1.3  mrg 		    ++k;
    804  1.1.1.3  mrg 		  start_data->ts.place_partition_off = p;
    805  1.1.1.3  mrg 		  start_data->ts.place_partition_len = 1;
    806  1.1.1.3  mrg 		}
    807  1.1.1.3  mrg 	      break;
    808  1.1.1.3  mrg 	    }
    809  1.1.1.3  mrg 	  start_data->place = p + 1;
    810  1.1.1.3  mrg 	  if (affinity_thr != NULL && pool->threads[i] != NULL)
    811  1.1.1.3  mrg 	    continue;
    812  1.1.1.3  mrg 	  gomp_init_thread_affinity (attr, p);
    813  1.1.1.3  mrg 	}
    814  1.1.1.3  mrg 
    815      1.1  mrg       start_data->fn = fn;
    816      1.1  mrg       start_data->fn_data = data;
    817      1.1  mrg       start_data->ts.team = team;
    818      1.1  mrg       start_data->ts.work_share = &team->work_shares[0];
    819      1.1  mrg       start_data->ts.last_work_share = NULL;
    820      1.1  mrg       start_data->ts.team_id = i;
    821      1.1  mrg       start_data->ts.level = team->prev_ts.level + 1;
    822      1.1  mrg       start_data->ts.active_level = thr->ts.active_level;
    823      1.1  mrg #ifdef HAVE_SYNC_BUILTINS
    824      1.1  mrg       start_data->ts.single_count = 0;
    825      1.1  mrg #endif
    826      1.1  mrg       start_data->ts.static_trip = 0;
    827      1.1  mrg       start_data->task = &team->implicit_task[i];
    828      1.1  mrg       gomp_init_task (start_data->task, task, icv);
    829  1.1.1.2  mrg       team->implicit_task[i].icv.nthreads_var = nthreads_var;
    830  1.1.1.3  mrg       team->implicit_task[i].icv.bind_var = bind_var;
    831  1.1.1.9  mrg       start_data->task->taskgroup = taskgroup;
    832      1.1  mrg       start_data->thread_pool = pool;
    833      1.1  mrg       start_data->nested = nested;
    834      1.1  mrg 
    835  1.1.1.4  mrg       attr = gomp_adjust_thread_attr (attr, &thread_attr);
    836  1.1.1.9  mrg       err = pthread_create (&start_data->handle, attr, gomp_thread_start,
    837  1.1.1.9  mrg 			    start_data);
    838  1.1.1.9  mrg       start_data++;
    839      1.1  mrg       if (err != 0)
    840      1.1  mrg 	gomp_fatal ("Thread creation failed: %s", strerror (err));
    841      1.1  mrg     }
    842      1.1  mrg 
    843  1.1.1.4  mrg   if (__builtin_expect (attr == &thread_attr, 0))
    844      1.1  mrg     pthread_attr_destroy (&thread_attr);
    845      1.1  mrg 
    846      1.1  mrg  do_release:
    847  1.1.1.5  mrg   if (nested)
    848  1.1.1.5  mrg     gomp_barrier_wait (&team->barrier);
    849  1.1.1.5  mrg   else
    850  1.1.1.5  mrg     gomp_simple_barrier_wait (&pool->threads_dock);
    851      1.1  mrg 
    852      1.1  mrg   /* Decrease the barrier threshold to match the number of threads
    853      1.1  mrg      that should arrive back at the end of this team.  The extra
    854      1.1  mrg      threads should be exiting.  Note that we arrange for this test
    855  1.1.1.3  mrg      to never be true for nested teams.  If AFFINITY_COUNT is non-zero,
    856  1.1.1.3  mrg      the barrier as well as gomp_managed_threads was temporarily
    857  1.1.1.3  mrg      set to NTHREADS + AFFINITY_COUNT.  For NTHREADS < OLD_THREADS_COUNT,
    858  1.1.1.3  mrg      AFFINITY_COUNT if non-zero will be always at least
    859  1.1.1.3  mrg      OLD_THREADS_COUNT - NTHREADS.  */
    860  1.1.1.3  mrg   if (__builtin_expect (nthreads < old_threads_used, 0)
    861  1.1.1.3  mrg       || __builtin_expect (affinity_count, 0))
    862      1.1  mrg     {
    863      1.1  mrg       long diff = (long) nthreads - (long) old_threads_used;
    864      1.1  mrg 
    865  1.1.1.3  mrg       if (affinity_count)
    866  1.1.1.3  mrg 	diff = -affinity_count;
    867  1.1.1.3  mrg 
    868  1.1.1.5  mrg       gomp_simple_barrier_reinit (&pool->threads_dock, nthreads);
    869      1.1  mrg 
    870      1.1  mrg #ifdef HAVE_SYNC_BUILTINS
    871      1.1  mrg       __sync_fetch_and_add (&gomp_managed_threads, diff);
    872      1.1  mrg #else
    873  1.1.1.3  mrg       gomp_mutex_lock (&gomp_managed_threads_lock);
    874      1.1  mrg       gomp_managed_threads += diff;
    875  1.1.1.3  mrg       gomp_mutex_unlock (&gomp_managed_threads_lock);
    876      1.1  mrg #endif
    877      1.1  mrg     }
    878  1.1.1.9  mrg   if (__builtin_expect (gomp_display_affinity_var, 0))
    879  1.1.1.9  mrg     {
    880  1.1.1.9  mrg       if (nested
    881  1.1.1.9  mrg 	  || nthreads != old_threads_used
    882  1.1.1.9  mrg 	  || force_display)
    883  1.1.1.9  mrg 	{
    884  1.1.1.9  mrg 	  gomp_display_affinity_thread (gomp_thread_self (), &thr->ts,
    885  1.1.1.9  mrg 					thr->place);
    886  1.1.1.9  mrg 	  if (nested)
    887  1.1.1.9  mrg 	    {
    888  1.1.1.9  mrg 	      start_data -= nthreads - 1;
    889  1.1.1.9  mrg 	      for (i = 1; i < nthreads; ++i)
    890  1.1.1.9  mrg 		{
    891  1.1.1.9  mrg 		  gomp_display_affinity_thread (
    892  1.1.1.9  mrg #ifdef LIBGOMP_USE_PTHREADS
    893  1.1.1.9  mrg 						start_data->handle,
    894  1.1.1.9  mrg #else
    895  1.1.1.9  mrg 						gomp_thread_self (),
    896  1.1.1.9  mrg #endif
    897  1.1.1.9  mrg 						&start_data->ts,
    898  1.1.1.9  mrg 						start_data->place);
    899  1.1.1.9  mrg 		  start_data++;
    900  1.1.1.9  mrg 		}
    901  1.1.1.9  mrg 	    }
    902  1.1.1.9  mrg 	  else
    903  1.1.1.9  mrg 	    {
    904  1.1.1.9  mrg 	      for (i = 1; i < nthreads; ++i)
    905  1.1.1.9  mrg 		{
    906  1.1.1.9  mrg 		  gomp_thread_handle handle
    907  1.1.1.9  mrg 		    = gomp_thread_to_pthread_t (pool->threads[i]);
    908  1.1.1.9  mrg 		  gomp_display_affinity_thread (handle, &pool->threads[i]->ts,
    909  1.1.1.9  mrg 						pool->threads[i]->place);
    910  1.1.1.9  mrg 		}
    911  1.1.1.9  mrg 	    }
    912  1.1.1.9  mrg 	}
    913  1.1.1.9  mrg     }
    914  1.1.1.3  mrg   if (__builtin_expect (affinity_thr != NULL, 0)
    915  1.1.1.3  mrg       && team->prev_ts.place_partition_len > 64)
    916  1.1.1.3  mrg     free (affinity_thr);
    917      1.1  mrg }
    918  1.1.1.5  mrg #endif
    919      1.1  mrg 
    920      1.1  mrg 
    921      1.1  mrg /* Terminate the current team.  This is only to be called by the master
    922      1.1  mrg    thread.  We assume that we must wait for the other threads.  */
    923      1.1  mrg 
    924      1.1  mrg void
    925      1.1  mrg gomp_team_end (void)
    926      1.1  mrg {
    927      1.1  mrg   struct gomp_thread *thr = gomp_thread ();
    928      1.1  mrg   struct gomp_team *team = thr->ts.team;
    929      1.1  mrg 
    930  1.1.1.3  mrg   /* This barrier handles all pending explicit threads.
    931  1.1.1.3  mrg      As #pragma omp cancel parallel might get awaited count in
    932  1.1.1.3  mrg      team->barrier in a inconsistent state, we need to use a different
    933  1.1.1.3  mrg      counter here.  */
    934  1.1.1.3  mrg   gomp_team_barrier_wait_final (&team->barrier);
    935  1.1.1.3  mrg   if (__builtin_expect (team->team_cancelled, 0))
    936  1.1.1.3  mrg     {
    937  1.1.1.3  mrg       struct gomp_work_share *ws = team->work_shares_to_free;
    938  1.1.1.3  mrg       do
    939  1.1.1.3  mrg 	{
    940  1.1.1.3  mrg 	  struct gomp_work_share *next_ws = gomp_ptrlock_get (&ws->next_ws);
    941  1.1.1.3  mrg 	  if (next_ws == NULL)
    942  1.1.1.3  mrg 	    gomp_ptrlock_set (&ws->next_ws, ws);
    943  1.1.1.3  mrg 	  gomp_fini_work_share (ws);
    944  1.1.1.3  mrg 	  ws = next_ws;
    945  1.1.1.3  mrg 	}
    946  1.1.1.3  mrg       while (ws != NULL);
    947  1.1.1.3  mrg     }
    948  1.1.1.3  mrg   else
    949  1.1.1.3  mrg     gomp_fini_work_share (thr->ts.work_share);
    950      1.1  mrg 
    951      1.1  mrg   gomp_end_task ();
    952      1.1  mrg   thr->ts = team->prev_ts;
    953      1.1  mrg 
    954  1.1.1.9  mrg   if (__builtin_expect (thr->ts.level != 0, 0))
    955      1.1  mrg     {
    956      1.1  mrg #ifdef HAVE_SYNC_BUILTINS
    957      1.1  mrg       __sync_fetch_and_add (&gomp_managed_threads, 1L - team->nthreads);
    958      1.1  mrg #else
    959  1.1.1.3  mrg       gomp_mutex_lock (&gomp_managed_threads_lock);
    960      1.1  mrg       gomp_managed_threads -= team->nthreads - 1L;
    961  1.1.1.3  mrg       gomp_mutex_unlock (&gomp_managed_threads_lock);
    962      1.1  mrg #endif
    963      1.1  mrg       /* This barrier has gomp_barrier_wait_last counterparts
    964      1.1  mrg 	 and ensures the team can be safely destroyed.  */
    965      1.1  mrg       gomp_barrier_wait (&team->barrier);
    966      1.1  mrg     }
    967      1.1  mrg 
    968      1.1  mrg   if (__builtin_expect (team->work_shares[0].next_alloc != NULL, 0))
    969      1.1  mrg     {
    970      1.1  mrg       struct gomp_work_share *ws = team->work_shares[0].next_alloc;
    971      1.1  mrg       do
    972      1.1  mrg 	{
    973      1.1  mrg 	  struct gomp_work_share *next_ws = ws->next_alloc;
    974      1.1  mrg 	  free (ws);
    975      1.1  mrg 	  ws = next_ws;
    976      1.1  mrg 	}
    977      1.1  mrg       while (ws != NULL);
    978      1.1  mrg     }
    979      1.1  mrg   gomp_sem_destroy (&team->master_release);
    980      1.1  mrg 
    981      1.1  mrg   if (__builtin_expect (thr->ts.team != NULL, 0)
    982      1.1  mrg       || __builtin_expect (team->nthreads == 1, 0))
    983      1.1  mrg     free_team (team);
    984      1.1  mrg   else
    985      1.1  mrg     {
    986      1.1  mrg       struct gomp_thread_pool *pool = thr->thread_pool;
    987      1.1  mrg       if (pool->last_team)
    988      1.1  mrg 	free_team (pool->last_team);
    989      1.1  mrg       pool->last_team = team;
    990  1.1.1.4  mrg       gomp_release_thread_pool (pool);
    991      1.1  mrg     }
    992      1.1  mrg }
    993      1.1  mrg 
    994  1.1.1.5  mrg #ifdef LIBGOMP_USE_PTHREADS
    995      1.1  mrg 
    996      1.1  mrg /* Constructors for this file.  */
    997      1.1  mrg 
    998      1.1  mrg static void __attribute__((constructor))
    999      1.1  mrg initialize_team (void)
   1000      1.1  mrg {
   1001  1.1.1.3  mrg #if !defined HAVE_TLS && !defined USE_EMUTLS
   1002      1.1  mrg   static struct gomp_thread initial_thread_tls_data;
   1003      1.1  mrg 
   1004      1.1  mrg   pthread_key_create (&gomp_tls_key, NULL);
   1005      1.1  mrg   pthread_setspecific (gomp_tls_key, &initial_thread_tls_data);
   1006      1.1  mrg #endif
   1007      1.1  mrg 
   1008      1.1  mrg   if (pthread_key_create (&gomp_thread_destructor, gomp_free_thread) != 0)
   1009      1.1  mrg     gomp_fatal ("could not create thread pool destructor.");
   1010      1.1  mrg }
   1011      1.1  mrg 
   1012      1.1  mrg static void __attribute__((destructor))
   1013      1.1  mrg team_destructor (void)
   1014      1.1  mrg {
   1015      1.1  mrg   /* Without this dlclose on libgomp could lead to subsequent
   1016      1.1  mrg      crashes.  */
   1017      1.1  mrg   pthread_key_delete (gomp_thread_destructor);
   1018      1.1  mrg }
   1019  1.1.1.9  mrg 
   1020  1.1.1.9  mrg /* Similar to gomp_free_pool_helper, but don't detach itself,
   1021  1.1.1.9  mrg    gomp_pause_host will pthread_join those threads.  */
   1022  1.1.1.9  mrg 
   1023  1.1.1.9  mrg static void
   1024  1.1.1.9  mrg gomp_pause_pool_helper (void *thread_pool)
   1025  1.1.1.9  mrg {
   1026  1.1.1.9  mrg   struct gomp_thread *thr = gomp_thread ();
   1027  1.1.1.9  mrg   struct gomp_thread_pool *pool
   1028  1.1.1.9  mrg     = (struct gomp_thread_pool *) thread_pool;
   1029  1.1.1.9  mrg   gomp_simple_barrier_wait_last (&pool->threads_dock);
   1030  1.1.1.9  mrg   gomp_sem_destroy (&thr->release);
   1031  1.1.1.9  mrg   thr->thread_pool = NULL;
   1032  1.1.1.9  mrg   thr->task = NULL;
   1033  1.1.1.9  mrg   pthread_exit (NULL);
   1034  1.1.1.9  mrg }
   1035  1.1.1.9  mrg 
   1036  1.1.1.9  mrg /* Free a thread pool and release its threads.  Return non-zero on
   1037  1.1.1.9  mrg    failure.  */
   1038  1.1.1.9  mrg 
   1039  1.1.1.9  mrg int
   1040  1.1.1.9  mrg gomp_pause_host (void)
   1041  1.1.1.9  mrg {
   1042  1.1.1.9  mrg   struct gomp_thread *thr = gomp_thread ();
   1043  1.1.1.9  mrg   struct gomp_thread_pool *pool = thr->thread_pool;
   1044  1.1.1.9  mrg   if (thr->ts.level)
   1045  1.1.1.9  mrg     return -1;
   1046  1.1.1.9  mrg   if (pool)
   1047  1.1.1.9  mrg     {
   1048  1.1.1.9  mrg       if (pool->threads_used > 0)
   1049  1.1.1.9  mrg 	{
   1050  1.1.1.9  mrg 	  int i;
   1051  1.1.1.9  mrg 	  pthread_t *thrs
   1052  1.1.1.9  mrg 	    = gomp_alloca (sizeof (pthread_t) * pool->threads_used);
   1053  1.1.1.9  mrg 	  for (i = 1; i < pool->threads_used; i++)
   1054  1.1.1.9  mrg 	    {
   1055  1.1.1.9  mrg 	      struct gomp_thread *nthr = pool->threads[i];
   1056  1.1.1.9  mrg 	      nthr->fn = gomp_pause_pool_helper;
   1057  1.1.1.9  mrg 	      nthr->data = pool;
   1058  1.1.1.9  mrg 	      thrs[i] = gomp_thread_to_pthread_t (nthr);
   1059  1.1.1.9  mrg 	    }
   1060  1.1.1.9  mrg 	  /* This barrier undocks threads docked on pool->threads_dock.  */
   1061  1.1.1.9  mrg 	  gomp_simple_barrier_wait (&pool->threads_dock);
   1062  1.1.1.9  mrg 	  /* And this waits till all threads have called gomp_barrier_wait_last
   1063  1.1.1.9  mrg 	     in gomp_pause_pool_helper.  */
   1064  1.1.1.9  mrg 	  gomp_simple_barrier_wait (&pool->threads_dock);
   1065  1.1.1.9  mrg 	  /* Now it is safe to destroy the barrier and free the pool.  */
   1066  1.1.1.9  mrg 	  gomp_simple_barrier_destroy (&pool->threads_dock);
   1067  1.1.1.9  mrg 
   1068  1.1.1.9  mrg #ifdef HAVE_SYNC_BUILTINS
   1069  1.1.1.9  mrg 	  __sync_fetch_and_add (&gomp_managed_threads,
   1070  1.1.1.9  mrg 				1L - pool->threads_used);
   1071  1.1.1.9  mrg #else
   1072  1.1.1.9  mrg 	  gomp_mutex_lock (&gomp_managed_threads_lock);
   1073  1.1.1.9  mrg 	  gomp_managed_threads -= pool->threads_used - 1L;
   1074  1.1.1.9  mrg 	  gomp_mutex_unlock (&gomp_managed_threads_lock);
   1075  1.1.1.9  mrg #endif
   1076  1.1.1.9  mrg 	  for (i = 1; i < pool->threads_used; i++)
   1077  1.1.1.9  mrg 	    pthread_join (thrs[i], NULL);
   1078  1.1.1.9  mrg 	}
   1079  1.1.1.9  mrg       if (pool->last_team)
   1080  1.1.1.9  mrg 	free_team (pool->last_team);
   1081  1.1.1.9  mrg #ifndef __nvptx__
   1082  1.1.1.9  mrg       free (pool->threads);
   1083  1.1.1.9  mrg       free (pool);
   1084  1.1.1.9  mrg #endif
   1085  1.1.1.9  mrg       thr->thread_pool = NULL;
   1086  1.1.1.9  mrg     }
   1087  1.1.1.9  mrg   return 0;
   1088  1.1.1.9  mrg }
   1089  1.1.1.5  mrg #endif
   1090      1.1  mrg 
   1091      1.1  mrg struct gomp_task_icv *
   1092      1.1  mrg gomp_new_icv (void)
   1093      1.1  mrg {
   1094      1.1  mrg   struct gomp_thread *thr = gomp_thread ();
   1095      1.1  mrg   struct gomp_task *task = gomp_malloc (sizeof (struct gomp_task));
   1096      1.1  mrg   gomp_init_task (task, NULL, &gomp_global_icv);
   1097      1.1  mrg   thr->task = task;
   1098  1.1.1.5  mrg #ifdef LIBGOMP_USE_PTHREADS
   1099      1.1  mrg   pthread_setspecific (gomp_thread_destructor, thr);
   1100  1.1.1.5  mrg #endif
   1101      1.1  mrg   return &task->icv;
   1102      1.1  mrg }
   1103