xref: /netbsd-src/external/gpl3/gcc.old/dist/libgomp/single.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
1*8feb0f0bSmrg /* Copyright (C) 2005-2020 Free Software Foundation, Inc.
21debfc3dSmrg    Contributed by Richard Henderson <rth@redhat.com>.
31debfc3dSmrg 
41debfc3dSmrg    This file is part of the GNU Offloading and Multi Processing Library
51debfc3dSmrg    (libgomp).
61debfc3dSmrg 
71debfc3dSmrg    Libgomp is free software; you can redistribute it and/or modify it
81debfc3dSmrg    under the terms of the GNU General Public License as published by
91debfc3dSmrg    the Free Software Foundation; either version 3, or (at your option)
101debfc3dSmrg    any later version.
111debfc3dSmrg 
121debfc3dSmrg    Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
131debfc3dSmrg    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
141debfc3dSmrg    FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
151debfc3dSmrg    more details.
161debfc3dSmrg 
171debfc3dSmrg    Under Section 7 of GPL version 3, you are granted additional
181debfc3dSmrg    permissions described in the GCC Runtime Library Exception, version
191debfc3dSmrg    3.1, as published by the Free Software Foundation.
201debfc3dSmrg 
211debfc3dSmrg    You should have received a copy of the GNU General Public License and
221debfc3dSmrg    a copy of the GCC Runtime Library Exception along with this program;
231debfc3dSmrg    see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
241debfc3dSmrg    <http://www.gnu.org/licenses/>.  */
251debfc3dSmrg 
261debfc3dSmrg /* This file handles the SINGLE construct.  */
271debfc3dSmrg 
281debfc3dSmrg #include "libgomp.h"
291debfc3dSmrg 
301debfc3dSmrg 
311debfc3dSmrg /* This routine is called when first encountering a SINGLE construct that
321debfc3dSmrg    doesn't have a COPYPRIVATE clause.  Returns true if this is the thread
331debfc3dSmrg    that should execute the clause.  */
341debfc3dSmrg 
351debfc3dSmrg bool
GOMP_single_start(void)361debfc3dSmrg GOMP_single_start (void)
371debfc3dSmrg {
381debfc3dSmrg #ifdef HAVE_SYNC_BUILTINS
391debfc3dSmrg   struct gomp_thread *thr = gomp_thread ();
401debfc3dSmrg   struct gomp_team *team = thr->ts.team;
411debfc3dSmrg   unsigned long single_count;
421debfc3dSmrg 
431debfc3dSmrg   if (__builtin_expect (team == NULL, 0))
441debfc3dSmrg     return true;
451debfc3dSmrg 
461debfc3dSmrg   single_count = thr->ts.single_count++;
471debfc3dSmrg   return __sync_bool_compare_and_swap (&team->single_count, single_count,
481debfc3dSmrg 				       single_count + 1L);
491debfc3dSmrg #else
50c0a68be4Smrg   bool ret = gomp_work_share_start (0);
511debfc3dSmrg   if (ret)
521debfc3dSmrg     gomp_work_share_init_done ();
531debfc3dSmrg   gomp_work_share_end_nowait ();
541debfc3dSmrg   return ret;
551debfc3dSmrg #endif
561debfc3dSmrg }
571debfc3dSmrg 
581debfc3dSmrg /* This routine is called when first encountering a SINGLE construct that
591debfc3dSmrg    does have a COPYPRIVATE clause.  Returns NULL if this is the thread
601debfc3dSmrg    that should execute the clause; otherwise the return value is pointer
611debfc3dSmrg    given to GOMP_single_copy_end by the thread that did execute the clause.  */
621debfc3dSmrg 
631debfc3dSmrg void *
GOMP_single_copy_start(void)641debfc3dSmrg GOMP_single_copy_start (void)
651debfc3dSmrg {
661debfc3dSmrg   struct gomp_thread *thr = gomp_thread ();
671debfc3dSmrg 
681debfc3dSmrg   bool first;
691debfc3dSmrg   void *ret;
701debfc3dSmrg 
71c0a68be4Smrg   first = gomp_work_share_start (0);
721debfc3dSmrg 
731debfc3dSmrg   if (first)
741debfc3dSmrg     {
751debfc3dSmrg       gomp_work_share_init_done ();
761debfc3dSmrg       ret = NULL;
771debfc3dSmrg     }
781debfc3dSmrg   else
791debfc3dSmrg     {
801debfc3dSmrg       gomp_team_barrier_wait (&thr->ts.team->barrier);
811debfc3dSmrg 
821debfc3dSmrg       ret = thr->ts.work_share->copyprivate;
831debfc3dSmrg       gomp_work_share_end_nowait ();
841debfc3dSmrg     }
851debfc3dSmrg 
861debfc3dSmrg   return ret;
871debfc3dSmrg }
881debfc3dSmrg 
891debfc3dSmrg /* This routine is called when the thread that entered a SINGLE construct
901debfc3dSmrg    with a COPYPRIVATE clause gets to the end of the construct.  */
911debfc3dSmrg 
921debfc3dSmrg void
GOMP_single_copy_end(void * data)931debfc3dSmrg GOMP_single_copy_end (void *data)
941debfc3dSmrg {
951debfc3dSmrg   struct gomp_thread *thr = gomp_thread ();
961debfc3dSmrg   struct gomp_team *team = thr->ts.team;
971debfc3dSmrg 
981debfc3dSmrg   if (team != NULL)
991debfc3dSmrg     {
1001debfc3dSmrg       thr->ts.work_share->copyprivate = data;
1011debfc3dSmrg       gomp_team_barrier_wait (&team->barrier);
1021debfc3dSmrg     }
1031debfc3dSmrg 
1041debfc3dSmrg   gomp_work_share_end_nowait ();
1051debfc3dSmrg }
106