single.c

Go to the documentation of this file.
00001 /* Copyright (C) 2005, 2008, 2009 Free Software Foundation, Inc.
00002    Contributed by Richard Henderson <rth@redhat.com>.
00003 
00004    This file is part of the GNU OpenMP Library (libgomp).
00005 
00006    Libgomp is free software; you can redistribute it and/or modify it
00007    under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 3, or (at your option)
00009    any later version.
00010 
00011    Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
00012    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00013    FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
00014    more details.
00015 
00016    Under Section 7 of GPL version 3, you are granted additional
00017    permissions described in the GCC Runtime Library Exception, version
00018    3.1, as published by the Free Software Foundation.
00019 
00020    You should have received a copy of the GNU General Public License and
00021    a copy of the GCC Runtime Library Exception along with this program;
00022    see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023    <http://www.gnu.org/licenses/>.  */
00024 
00025 /* This file handles the SINGLE construct.  */
00026 
00027 #include "libgomp.h"
00028 
00029 
00030 /* This routine is called when first encountering a SINGLE construct that
00031    doesn't have a COPYPRIVATE clause.  Returns true if this is the thread
00032    that should execute the clause.  */
00033 
00034 bool
00035 GOMP_single_start (void)
00036 {
00037 #ifdef HAVE_SYNC_BUILTINS
00038   struct gomp_thread *thr = gomp_thread ();
00039   struct gomp_team *team = thr->ts.team;
00040   unsigned long single_count;
00041 
00042   if (__builtin_expect (team == NULL, 0))
00043     return true;
00044 
00045   single_count = thr->ts.single_count++;
00046   return __sync_bool_compare_and_swap (&team->single_count, single_count,
00047                        single_count + 1L);
00048 #else
00049   bool ret = gomp_work_share_start (false);
00050   if (ret)
00051     gomp_work_share_init_done ();
00052   gomp_work_share_end_nowait ();
00053   return ret;
00054 #endif
00055 }
00056 
00057 /* This routine is called when first encountering a SINGLE construct that
00058    does have a COPYPRIVATE clause.  Returns NULL if this is the thread
00059    that should execute the clause; otherwise the return value is pointer
00060    given to GOMP_single_copy_end by the thread that did execute the clause.  */
00061 
00062 void *
00063 GOMP_single_copy_start (void)
00064 {
00065   struct gomp_thread *thr = gomp_thread ();
00066 
00067   bool first;
00068   void *ret;
00069 
00070   first = gomp_work_share_start (false);
00071   
00072   if (first)
00073     {
00074       gomp_work_share_init_done ();
00075       ret = NULL;
00076     }
00077   else
00078     {
00079       gomp_team_barrier_wait (&thr->ts.team->barrier);
00080 
00081       ret = thr->ts.work_share->copyprivate;
00082       gomp_work_share_end_nowait ();
00083     }
00084 
00085   return ret;
00086 }
00087 
00088 /* This routine is called when the thread that entered a SINGLE construct
00089    with a COPYPRIVATE clause gets to the end of the construct.  */
00090 
00091 void
00092 GOMP_single_copy_end (void *data)
00093 {
00094   struct gomp_thread *thr = gomp_thread ();
00095   struct gomp_team *team = thr->ts.team;
00096 
00097   if (team != NULL)
00098     {
00099       thr->ts.work_share->copyprivate = data;
00100       gomp_team_barrier_wait (&team->barrier);
00101     }
00102 
00103   gomp_work_share_end_nowait ();
00104 }

Generated on Fri Apr 5 05:38:10 2013 for Libgomp by  doxygen 1.4.7