xref: /dflybsd-src/contrib/gcc-4.7/libgomp/single.c (revision 94b98a915ba84699b2a2adab9146fbc2cf617459)
1*629ff9f7SJohn Marino /* Copyright (C) 2005, 2008, 2009 Free Software Foundation, Inc.
2*629ff9f7SJohn Marino    Contributed by Richard Henderson <rth@redhat.com>.
3*629ff9f7SJohn Marino 
4*629ff9f7SJohn Marino    This file is part of the GNU OpenMP Library (libgomp).
5*629ff9f7SJohn Marino 
6*629ff9f7SJohn Marino    Libgomp is free software; you can redistribute it and/or modify it
7*629ff9f7SJohn Marino    under the terms of the GNU General Public License as published by
8*629ff9f7SJohn Marino    the Free Software Foundation; either version 3, or (at your option)
9*629ff9f7SJohn Marino    any later version.
10*629ff9f7SJohn Marino 
11*629ff9f7SJohn Marino    Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
12*629ff9f7SJohn Marino    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13*629ff9f7SJohn Marino    FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14*629ff9f7SJohn Marino    more details.
15*629ff9f7SJohn Marino 
16*629ff9f7SJohn Marino    Under Section 7 of GPL version 3, you are granted additional
17*629ff9f7SJohn Marino    permissions described in the GCC Runtime Library Exception, version
18*629ff9f7SJohn Marino    3.1, as published by the Free Software Foundation.
19*629ff9f7SJohn Marino 
20*629ff9f7SJohn Marino    You should have received a copy of the GNU General Public License and
21*629ff9f7SJohn Marino    a copy of the GCC Runtime Library Exception along with this program;
22*629ff9f7SJohn Marino    see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23*629ff9f7SJohn Marino    <http://www.gnu.org/licenses/>.  */
24*629ff9f7SJohn Marino 
25*629ff9f7SJohn Marino /* This file handles the SINGLE construct.  */
26*629ff9f7SJohn Marino 
27*629ff9f7SJohn Marino #include "libgomp.h"
28*629ff9f7SJohn Marino 
29*629ff9f7SJohn Marino 
30*629ff9f7SJohn Marino /* This routine is called when first encountering a SINGLE construct that
31*629ff9f7SJohn Marino    doesn't have a COPYPRIVATE clause.  Returns true if this is the thread
32*629ff9f7SJohn Marino    that should execute the clause.  */
33*629ff9f7SJohn Marino 
34*629ff9f7SJohn Marino bool
GOMP_single_start(void)35*629ff9f7SJohn Marino GOMP_single_start (void)
36*629ff9f7SJohn Marino {
37*629ff9f7SJohn Marino #ifdef HAVE_SYNC_BUILTINS
38*629ff9f7SJohn Marino   struct gomp_thread *thr = gomp_thread ();
39*629ff9f7SJohn Marino   struct gomp_team *team = thr->ts.team;
40*629ff9f7SJohn Marino   unsigned long single_count;
41*629ff9f7SJohn Marino 
42*629ff9f7SJohn Marino   if (__builtin_expect (team == NULL, 0))
43*629ff9f7SJohn Marino     return true;
44*629ff9f7SJohn Marino 
45*629ff9f7SJohn Marino   single_count = thr->ts.single_count++;
46*629ff9f7SJohn Marino   return __sync_bool_compare_and_swap (&team->single_count, single_count,
47*629ff9f7SJohn Marino 				       single_count + 1L);
48*629ff9f7SJohn Marino #else
49*629ff9f7SJohn Marino   bool ret = gomp_work_share_start (false);
50*629ff9f7SJohn Marino   if (ret)
51*629ff9f7SJohn Marino     gomp_work_share_init_done ();
52*629ff9f7SJohn Marino   gomp_work_share_end_nowait ();
53*629ff9f7SJohn Marino   return ret;
54*629ff9f7SJohn Marino #endif
55*629ff9f7SJohn Marino }
56*629ff9f7SJohn Marino 
57*629ff9f7SJohn Marino /* This routine is called when first encountering a SINGLE construct that
58*629ff9f7SJohn Marino    does have a COPYPRIVATE clause.  Returns NULL if this is the thread
59*629ff9f7SJohn Marino    that should execute the clause; otherwise the return value is pointer
60*629ff9f7SJohn Marino    given to GOMP_single_copy_end by the thread that did execute the clause.  */
61*629ff9f7SJohn Marino 
62*629ff9f7SJohn Marino void *
GOMP_single_copy_start(void)63*629ff9f7SJohn Marino GOMP_single_copy_start (void)
64*629ff9f7SJohn Marino {
65*629ff9f7SJohn Marino   struct gomp_thread *thr = gomp_thread ();
66*629ff9f7SJohn Marino 
67*629ff9f7SJohn Marino   bool first;
68*629ff9f7SJohn Marino   void *ret;
69*629ff9f7SJohn Marino 
70*629ff9f7SJohn Marino   first = gomp_work_share_start (false);
71*629ff9f7SJohn Marino 
72*629ff9f7SJohn Marino   if (first)
73*629ff9f7SJohn Marino     {
74*629ff9f7SJohn Marino       gomp_work_share_init_done ();
75*629ff9f7SJohn Marino       ret = NULL;
76*629ff9f7SJohn Marino     }
77*629ff9f7SJohn Marino   else
78*629ff9f7SJohn Marino     {
79*629ff9f7SJohn Marino       gomp_team_barrier_wait (&thr->ts.team->barrier);
80*629ff9f7SJohn Marino 
81*629ff9f7SJohn Marino       ret = thr->ts.work_share->copyprivate;
82*629ff9f7SJohn Marino       gomp_work_share_end_nowait ();
83*629ff9f7SJohn Marino     }
84*629ff9f7SJohn Marino 
85*629ff9f7SJohn Marino   return ret;
86*629ff9f7SJohn Marino }
87*629ff9f7SJohn Marino 
88*629ff9f7SJohn Marino /* This routine is called when the thread that entered a SINGLE construct
89*629ff9f7SJohn Marino    with a COPYPRIVATE clause gets to the end of the construct.  */
90*629ff9f7SJohn Marino 
91*629ff9f7SJohn Marino void
GOMP_single_copy_end(void * data)92*629ff9f7SJohn Marino GOMP_single_copy_end (void *data)
93*629ff9f7SJohn Marino {
94*629ff9f7SJohn Marino   struct gomp_thread *thr = gomp_thread ();
95*629ff9f7SJohn Marino   struct gomp_team *team = thr->ts.team;
96*629ff9f7SJohn Marino 
97*629ff9f7SJohn Marino   if (team != NULL)
98*629ff9f7SJohn Marino     {
99*629ff9f7SJohn Marino       thr->ts.work_share->copyprivate = data;
100*629ff9f7SJohn Marino       gomp_team_barrier_wait (&team->barrier);
101*629ff9f7SJohn Marino     }
102*629ff9f7SJohn Marino 
103*629ff9f7SJohn Marino   gomp_work_share_end_nowait ();
104*629ff9f7SJohn Marino }
105