OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / libgomp / team.c
index 18b02e7..110bd47 100644 (file)
@@ -1,29 +1,27 @@
-/* Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006, 2007, 2008, 2009, 2011, 2012
+   Free Software Foundation, Inc.
    Contributed by Richard Henderson <rth@redhat.com>.
 
    This file is part of the GNU OpenMP Library (libgomp).
 
    Libgomp is free software; you can redistribute it and/or modify it
-   under the terms of the GNU Lesser General Public License as published by
-   the Free Software Foundation; either version 2.1 of the License, or
-   (at your option) any later version.
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
 
    Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-   FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
+   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    more details.
 
-   You should have received a copy of the GNU Lesser General Public License 
-   along with libgomp; see the file COPYING.LIB.  If not, write to the
-   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-   MA 02110-1301, USA.  */
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
 
-/* As a special exception, if you link this library with other files, some
-   of which are compiled with GCC, to produce an executable, this library
-   does not by itself cause the resulting executable to be covered by the
-   GNU General Public License.  This exception does not however invalidate
-   any other reasons why the executable file might be covered by the GNU
-   General Public License.  */
+   You should have received a copy of the GNU General Public License and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   <http://www.gnu.org/licenses/>.  */
 
 /* This file handles the maintainence of threads in response to team
    creation and termination.  */
@@ -128,6 +126,7 @@ gomp_thread_start (void *xdata)
       while (local_fn);
     }
 
+  gomp_sem_destroy (&thr->release);
   return NULL;
 }
 
@@ -204,6 +203,7 @@ gomp_free_pool_helper (void *thread_pool)
   struct gomp_thread_pool *pool
     = (struct gomp_thread_pool *) thread_pool;
   gomp_barrier_wait_last (&pool->threads_dock);
+  gomp_sem_destroy (&gomp_thread ()->release);
   pthread_exit (NULL);
 }
 
@@ -232,6 +232,15 @@ gomp_free_thread (void *arg __attribute__((unused)))
          gomp_barrier_wait (&pool->threads_dock);
          /* Now it is safe to destroy the barrier and free the pool.  */
          gomp_barrier_destroy (&pool->threads_dock);
+
+#ifdef HAVE_SYNC_BUILTINS
+         __sync_fetch_and_add (&gomp_managed_threads,
+                               1L - pool->threads_used);
+#else
+         gomp_mutex_lock (&gomp_remaining_threads_lock);
+         gomp_managed_threads -= pool->threads_used - 1L;
+         gomp_mutex_unlock (&gomp_remaining_threads_lock);
+#endif
        }
       free (pool->threads);
       if (pool->last_team)
@@ -261,6 +270,7 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
   struct gomp_thread_pool *pool;
   unsigned i, n, old_threads_used = 0;
   pthread_attr_t thread_attr, *attr;
+  unsigned long nthreads_var;
 
   thr = gomp_thread ();
   nested = thr->ts.team != NULL;
@@ -290,7 +300,12 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
 #endif
   thr->ts.static_trip = 0;
   thr->task = &team->implicit_task[0];
+  nthreads_var = icv->nthreads_var;
+  if (__builtin_expect (gomp_nthreads_var_list != NULL, 0)
+      && thr->ts.level < gomp_nthreads_var_list_len)
+    nthreads_var = gomp_nthreads_var_list[thr->ts.level];
   gomp_init_task (thr->task, task, icv);
+  team->implicit_task[0].icv.nthreads_var = nthreads_var;
 
   if (nthreads == 1)
     return;
@@ -343,6 +358,7 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
          nthr->ts.static_trip = 0;
          nthr->task = &team->implicit_task[i];
          gomp_init_task (nthr->task, task, icv);
+         team->implicit_task[i].icv.nthreads_var = nthreads_var;
          nthr->fn = fn;
          nthr->data = data;
          team->ordered_release[i] = &nthr->release;
@@ -414,6 +430,7 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
       start_data->ts.static_trip = 0;
       start_data->task = &team->implicit_task[i];
       gomp_init_task (start_data->task, task, icv);
+      team->implicit_task[i].icv.nthreads_var = nthreads_var;
       start_data->thread_pool = pool;
       start_data->nested = nested;
 
@@ -498,7 +515,8 @@ gomp_team_end (void)
   gomp_mutex_destroy (&team->work_share_list_free_lock);
 #endif
 
-  if (__builtin_expect (thr->ts.team != NULL, 0))
+  if (__builtin_expect (thr->ts.team != NULL, 0)
+      || __builtin_expect (team->nthreads == 1, 0))
     free_team (team);
   else
     {