From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25115 invoked by alias); 18 Mar 2008 09:54:18 -0000 Received: (qmail 25100 invoked by uid 22791); 18 Mar 2008 09:54:17 -0000 X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 18 Mar 2008 09:53:56 +0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id m2I9rsnj019113 for ; Tue, 18 Mar 2008 05:53:54 -0400 Received: from devserv.devel.redhat.com (devserv.devel.redhat.com [10.10.36.72]) by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id m2I9rsB0012466 for ; Tue, 18 Mar 2008 05:53:54 -0400 Received: from devserv.devel.redhat.com (localhost.localdomain [127.0.0.1]) by devserv.devel.redhat.com (8.12.11.20060308/8.12.11) with ESMTP id m2I9rs9H032351 for ; Tue, 18 Mar 2008 05:53:54 -0400 Received: (from jakub@localhost) by devserv.devel.redhat.com (8.12.11.20060308/8.12.11/Submit) id m2I9rskl032349 for gcc-patches@gcc.gnu.org; Tue, 18 Mar 2008 05:53:54 -0400 Date: Tue, 18 Mar 2008 09:56:00 -0000 From: Jakub Jelinek To: gcc-patches@gcc.gnu.org Subject: [PATCH] Fix schedule(guided) Message-ID: <20080318095353.GG29754@devserv.devel.redhat.com> Reply-To: Jakub Jelinek Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4.1i X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2008-03/txt/msg01037.txt.bz2 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 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