This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix schedule(guided)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 18 Mar 2008 05:53:53 -0400
- Subject: [PATCH] Fix schedule(guided)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
The attached testcase loops forever. The problem is that during the last
iteration, ws->next and *pend is set to
ws->next + (ws->end - ws->next) / ws->incr * ws->incr
rather than
ws->end. This is last chunk, the only chunk with < chunksize iterations.
The termination condition where gomp_iter_guided_next* returns false is
ws->next == ws->end, so if (end - start) % incr != 0, then after the last
real chunk each following gomp_iter_guided_next* will return true and an
empty range.
Fixed thusly, regtested on x86_64-linux. Trunk/4.3.
2008-03-18 Jakub Jelinek <jakub@redhat.com>
PR libgomp/35625
* iter.c (gomp_iter_guided_next_locked): If q > n, set end to ws->end.
(gomp_iter_guided_next): Likewise.
* testsuite/libgomp.c/pr35625.c: New test.
--- libgomp/iter.c.jj 2008-02-18 23:42:14.000000000 +0100
+++ libgomp/iter.c 2008-03-18 10:26:32.000000000 +0100
@@ -242,16 +242,16 @@ gomp_iter_guided_next_locked (long *psta
if (ws->next == ws->end)
return false;
- n = (ws->end - ws->next) / ws->incr;
+ start = ws->next;
+ n = (ws->end - start) / ws->incr;
q = (n + nthreads - 1) / nthreads;
if (q < ws->chunk_size)
q = ws->chunk_size;
- if (q > n)
- q = n;
-
- start = ws->next;
- end = start + q * ws->incr;
+ if (q <= n)
+ end = start + q * ws->incr;
+ else
+ end = ws->end;
ws->next = end;
*pstart = start;
@@ -286,15 +286,15 @@ gomp_iter_guided_next (long *pstart, lon
if (start == end)
return false;
- n = (end - start) / ws->incr;
+ n = (end - start) / incr;
q = (n + nthreads - 1) / nthreads;
if (q < chunk_size)
q = chunk_size;
- if (q > n)
- q = n;
-
- nend = start + q * incr;
+ if (__builtin_expect (q <= n, 1))
+ nend = start + q * incr;
+ else
+ nend = end;
tmp = __sync_val_compare_and_swap (&ws->next, start, nend);
if (__builtin_expect (tmp == start, 1))
--- libgomp/testsuite/libgomp.c/pr35625.c.jj 2008-03-18 10:13:09.000000000 +0100
+++ libgomp/testsuite/libgomp.c/pr35625.c 2008-03-18 10:31:58.000000000 +0100
@@ -0,0 +1,18 @@
+/* PR libgomp/35625 */
+/* { dg-do run } */
+/* { dg-options "-std=c99" } */
+
+int
+main (void)
+{
+#pragma omp parallel
+ {
+ #pragma omp for schedule (guided, 10)
+ for (int i = 0; i < 1826; i += 10)
+ ;
+ #pragma omp for schedule (guided, 10)
+ for (int i = 0; i > -1826; i -= 10)
+ ;
+ }
+ return 0;
+}
Jakub