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