1285SN/A/* Copyright (C) 2005 Free Software Foundation, Inc.
2759Saefimov   Contributed by Richard Henderson <rth@redhat.com>.
3285SN/A
4285SN/A   This file is part of the GNU OpenMP Library (libgomp).
5285SN/A
6285SN/A   Libgomp is free software; you can redistribute it and/or modify it
7285SN/A   under the terms of the GNU Lesser General Public License as published by
8285SN/A   the Free Software Foundation; either version 2.1 of the License, or
9285SN/A   (at your option) any later version.
10285SN/A
11285SN/A   Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
12285SN/A   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13285SN/A   FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
14285SN/A   more details.
15285SN/A
16285SN/A   You should have received a copy of the GNU Lesser General Public License
17285SN/A   along with libgomp; see the file COPYING.LIB.  If not, write to the
18285SN/A   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19285SN/A   MA 02110-1301, USA.  */
20285SN/A
21285SN/A/* As a special exception, if you link this library with other files, some
22285SN/A   of which are compiled with GCC, to produce an executable, this library
23285SN/A   does not by itself cause the resulting executable to be covered by the
24285SN/A   GNU General Public License.  This exception does not however invalidate
25285SN/A   any other reasons why the executable file might be covered by the GNU
26285SN/A   General Public License.  */
27285SN/A
28285SN/A/* This file handles the SINGLE construct.  */
29285SN/A
30285SN/A#include "libgomp.h"
31285SN/A
32759Saefimov
33759Saefimov/* This routine is called when first encountering a SINGLE construct that
34759Saefimov   doesn't have a COPYPRIVATE clause.  Returns true if this is the thread
35821Saefimov   that should execute the clause.  */
36821Saefimov
37759Saefimovbool
38759SaefimovGOMP_single_start (void)
39759Saefimov{
40759Saefimov  bool ret = gomp_work_share_start (false);
41759Saefimov  gomp_mutex_unlock (&gomp_thread ()->ts.work_share->lock);
42759Saefimov  gomp_work_share_end_nowait ();
43759Saefimov  return ret;
44821Saefimov}
45759Saefimov
46759Saefimov/* This routine is called when first encountering a SINGLE construct that
47759Saefimov   does have a COPYPRIVATE clause.  Returns NULL if this is the thread
48759Saefimov   that should execute the clause; otherwise the return value is pointer
49759Saefimov   given to GOMP_single_copy_end by the thread that did execute the clause.  */
50759Saefimov
51759Saefimovvoid *
52759SaefimovGOMP_single_copy_start (void)
53759Saefimov{
54759Saefimov  struct gomp_thread *thr = gomp_thread ();
55759Saefimov
56759Saefimov  bool first;
57759Saefimov  void *ret;
58821Saefimov
59759Saefimov  first = gomp_work_share_start (false);
60759Saefimov  gomp_mutex_unlock (&thr->ts.work_share->lock);
61759Saefimov
62759Saefimov  if (first)
63759Saefimov    ret = NULL;
64759Saefimov  else
65759Saefimov    {
66821Saefimov      gomp_barrier_wait (&thr->ts.team->barrier);
67759Saefimov
68285SN/A      ret = thr->ts.work_share->copyprivate;
69285SN/A      gomp_work_share_end_nowait ();
70759Saefimov    }
71285SN/A
72821Saefimov  return ret;
73821Saefimov}
74285SN/A
75285SN/A/* This routine is called when the thread that entered a SINGLE construct
76285SN/A   with a COPYPRIVATE clause gets to the end of the construct.  */
77285SN/A
78285SN/Avoid
79285SN/AGOMP_single_copy_end (void *data)
80285SN/A{
81759Saefimov  struct gomp_thread *thr = gomp_thread ();
82759Saefimov  struct gomp_team *team = thr->ts.team;
83285SN/A
84759Saefimov  if (team != NULL)
85285SN/A    {
86759Saefimov      thr->ts.work_share->copyprivate = data;
87759Saefimov      gomp_barrier_wait (&team->barrier);
88759Saefimov    }
89759Saefimov
90759Saefimov  gomp_work_share_end_nowait ();
91759Saefimov}
92759Saefimov