Hi!

This is the minimal fix for the issue mentioned in
http://gcc.gnu.org/ml/gcc-patches/2013-10/msg00333.html
that is being fixed as part of gomp-4_0-branch merge to trunk,
but for 4.8 I've applied this fix instead.
The testcase also includes the follow-up fix from
http://gcc.gnu.org/ml/gcc-patches/2013-10/msg00497.html

Bootstrapped/regtested on x86_64-linux and i686-linux, committed
to 4.8 branch.

2013-10-09  Jakub Jelinek  <ja...@redhat.com>

        * parallel.c (GOMP_parallel_end): Remember team->nthreads and call
        gomp_team_end before adjusting gomp_remaining_threads_count, increment
        gomp_remaining_threads_count instead of decrementing it again.
        * testsuite/libgomp.c/thread-limit-1.c: New test.

--- libgomp/parallel.c.jj       2013-03-16 08:07:43.000000000 +0100
+++ libgomp/parallel.c  2013-10-09 09:10:38.215245390 +0200
@@ -115,19 +115,22 @@ GOMP_parallel_end (void)
     {
       struct gomp_thread *thr = gomp_thread ();
       struct gomp_team *team = thr->ts.team;
-      if (team && team->nthreads > 1)
+      unsigned int nthreads = team ? team->nthreads : 1;
+      gomp_team_end ();
+      if (nthreads > 1)
        {
 #ifdef HAVE_SYNC_BUILTINS
          __sync_fetch_and_add (&gomp_remaining_threads_count,
-                               1UL - team->nthreads);
+                               nthreads - 1);
 #else
          gomp_mutex_lock (&gomp_remaining_threads_lock);
-         gomp_remaining_threads_count -= team->nthreads - 1;
+         gomp_remaining_threads_count += nthreads - 1;
          gomp_mutex_unlock (&gomp_remaining_threads_lock);
 #endif
        }
     }
-  gomp_team_end ();
+  else
+    gomp_team_end ();
 }
 
 
--- libgomp/testsuite/libgomp.c/thread-limit-1.c.jj     2013-10-09 
09:05:35.702854964 +0200
+++ libgomp/testsuite/libgomp.c/thread-limit-1.c        2013-10-08 
20:30:47.000000000 +0200
@@ -0,0 +1,41 @@
+/* { dg-do run } */
+/* { dg-set-target-env-var OMP_THREAD_LIMIT "6" } */
+
+#include <stdlib.h>
+#include <unistd.h>
+
+int
+main ()
+{
+  if (omp_get_thread_limit () != 6)
+    return 0;
+  omp_set_dynamic (0);
+  omp_set_nested (1);
+  #pragma omp parallel num_threads (3)
+  if (omp_get_num_threads () != 3)
+    abort ();
+  #pragma omp parallel num_threads (3)
+  if (omp_get_num_threads () != 3)
+    abort ();
+  #pragma omp parallel num_threads (8)
+  if (omp_get_num_threads () > 6)
+    abort ();
+  #pragma omp parallel num_threads (6)
+  if (omp_get_num_threads () != 6)
+    abort ();
+  int cnt = 0;
+  #pragma omp parallel num_threads (5)
+  #pragma omp parallel num_threads (5)
+  #pragma omp parallel num_threads (2)
+  {
+    int v;
+    #pragma omp atomic capture
+    v = ++cnt;
+    if (v > 6)
+      abort ();
+    usleep (10000);
+    #pragma omp atomic
+    --cnt;
+  }
+  return 0;
+}

        Jakub

Reply via email to