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