config/linux/bar.h

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 is a Linux specific implementation of a barrier synchronization
00026    mechanism for libgomp.  This type is private to the library.  This 
00027    implementation uses atomic instructions and the futex syscall.  */
00028 
00029 #ifndef GOMP_BARRIER_H
00030 #define GOMP_BARRIER_H 1
00031 
00032 #include "mutex.h"
00033 
00034 typedef struct
00035 {
00036   /* Make sure total/generation is in a mostly read cacheline, while
00037      awaited in a separate cacheline.  */
00038   unsigned total __attribute__((aligned (64)));
00039   unsigned generation;
00040   unsigned awaited __attribute__((aligned (64)));
00041 } gomp_barrier_t;
00042 typedef unsigned int gomp_barrier_state_t;
00043 
00044 static inline void gomp_barrier_init (gomp_barrier_t *bar, unsigned count)
00045 {
00046   bar->total = count;
00047   bar->awaited = count;
00048   bar->generation = 0;
00049 }
00050 
00051 static inline void gomp_barrier_reinit (gomp_barrier_t *bar, unsigned count)
00052 {
00053   __sync_fetch_and_add (&bar->awaited, count - bar->total);
00054   bar->total = count;
00055 }
00056 
00057 static inline void gomp_barrier_destroy (gomp_barrier_t *bar)
00058 {
00059 }
00060 
00061 extern void gomp_barrier_wait (gomp_barrier_t *);
00062 extern void gomp_barrier_wait_last (gomp_barrier_t *);
00063 extern void gomp_barrier_wait_end (gomp_barrier_t *, gomp_barrier_state_t);
00064 extern void gomp_team_barrier_wait (gomp_barrier_t *);
00065 extern void gomp_team_barrier_wait_end (gomp_barrier_t *,
00066                     gomp_barrier_state_t);
00067 extern void gomp_team_barrier_wake (gomp_barrier_t *, int);
00068 
00069 static inline gomp_barrier_state_t
00070 gomp_barrier_wait_start (gomp_barrier_t *bar)
00071 {
00072   unsigned int ret = bar->generation & ~3;
00073   /* Do we need any barrier here or is __sync_add_and_fetch acting
00074      as the needed LoadLoad barrier already?  */
00075   ret += __sync_add_and_fetch (&bar->awaited, -1) == 0;
00076   return ret;
00077 }
00078 
00079 static inline bool
00080 gomp_barrier_last_thread (gomp_barrier_state_t state)
00081 {
00082   return state & 1;
00083 }
00084 
00085 /* All the inlines below must be called with team->task_lock
00086    held.  */
00087 
00088 static inline void
00089 gomp_team_barrier_set_task_pending (gomp_barrier_t *bar)
00090 {
00091   bar->generation |= 1;
00092 }
00093 
00094 static inline void
00095 gomp_team_barrier_clear_task_pending (gomp_barrier_t *bar)
00096 {
00097   bar->generation &= ~1;
00098 }
00099 
00100 static inline void
00101 gomp_team_barrier_set_waiting_for_tasks (gomp_barrier_t *bar)
00102 {
00103   bar->generation |= 2;
00104 }
00105 
00106 static inline bool
00107 gomp_team_barrier_waiting_for_tasks (gomp_barrier_t *bar)
00108 {
00109   return (bar->generation & 2) != 0;
00110 }
00111 
00112 static inline void
00113 gomp_team_barrier_done (gomp_barrier_t *bar, gomp_barrier_state_t state)
00114 {
00115   bar->generation = (state & ~3) + 4;
00116 }
00117 
00118 #endif /* GOMP_BARRIER_H */

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