1 /* Copyright (C) 2005 Free Software Foundation, Inc. 2 Contributed by Richard Henderson <rth@redhat.com>. 3 4 This file is part of the GNU OpenMP Library (libgomp). 5 6 Libgomp is free software; you can redistribute it and/or modify it 7 under the terms of the GNU Lesser General Public License as published by 8 the Free Software Foundation; either version 2.1 of the License, or 9 (at your option) any later version. 10 11 Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY 12 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for 14 more details. 15 16 You should have received a copy of the GNU Lesser General Public License 17 along with libgomp; see the file COPYING.LIB. If not, write to the 18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 19 MA 02110-1301, USA. */ 20 21 /* As a special exception, if you link this library with other files, some 22 of which are compiled with GCC, to produce an executable, this library 23 does not by itself cause the resulting executable to be covered by the 24 GNU General Public License. This exception does not however invalidate 25 any other reasons why the executable file might be covered by the GNU 26 General Public License. */ 27 28 /* This file contains data types and function declarations that are not 29 part of the official OpenMP user interface. There are declarations 30 in here that are part of the GNU OpenMP ABI, in that the compiler is 31 required to know about them and use them. 32 33 The convention is that the all caps prefix "GOMP" is used group items 34 that are part of the external ABI, and the lower case prefix "gomp" 35 is used group items that are completely private to the library. */ 36 37 #ifndef LIBGOMP_H 38 #define LIBGOMP_H 1 39 40 #include "config.h" 41 #include "gstdint.h" 42 43 #include <pthread.h> 44 #include <stdbool.h> 45 46 #ifdef HAVE_ATTRIBUTE_VISIBILITY 47 # pragma GCC visibility push(hidden) 48 #endif 49 50 #include "sem.h" 51 #include "mutex.h" 52 #include "bar.h" 53 54 55 /* This structure contains the data to control one work-sharing construct, 56 either a LOOP (FOR/DO) or a SECTIONS. */ 57 58 enum gomp_schedule_type 59 { 60 GFS_STATIC, 61 GFS_DYNAMIC, 62 GFS_GUIDED, 63 GFS_RUNTIME 64 }; 65 66 struct gomp_work_share 67 { 68 /* This member records the SCHEDULE clause to be used for this construct. 69 The user specification of "runtime" will already have been resolved. 70 If this is a SECTIONS construct, this value will always be DYNAMIC. */ 71 enum gomp_schedule_type sched; 72 73 /* This is the chunk_size argument to the SCHEDULE clause. */ 74 long chunk_size; 75 76 /* This is the iteration end point. If this is a SECTIONS construct, 77 this is the number of contained sections. */ 78 long end; 79 80 /* This is the iteration step. If this is a SECTIONS construct, this 81 is always 1. */ 82 long incr; 83 84 /* This lock protects the update of the following members. */ 85 gomp_mutex_t lock; 86 87 union { 88 /* This is the next iteration value to be allocated. In the case of 89 GFS_STATIC loops, this the iteration start point and never changes. */ 90 long next; 91 92 /* This is the returned data structure for SINGLE COPYPRIVATE. */ 93 void *copyprivate; 94 }; 95 96 /* This is the count of the number of threads that have exited the work 97 share construct. If the construct was marked nowait, they have moved on 98 to other work; otherwise they're blocked on a barrier. The last member 99 of the team to exit the work share construct must deallocate it. */ 100 unsigned threads_completed; 101 102 /* This is the index into the circular queue ordered_team_ids of the 103 current thread that's allowed into the ordered reason. */ 104 unsigned ordered_cur; 105 106 /* This is the number of threads that have registered themselves in 107 the circular queue ordered_team_ids. */ 108 unsigned ordered_num_used; 109 110 /* This is the team_id of the currently acknoledged owner of the ordered 111 section, or -1u if the ordered section has not been acknowledged by 112 any thread. This is distinguished from the thread that is *allowed* 113 to take the section next. */ 114 unsigned ordered_owner; 115 116 /* This is a circular queue that details which threads will be allowed 117 into the ordered region and in which order. When a thread allocates 118 iterations on which it is going to work, it also registers itself at 119 the end of the array. When a thread reaches the ordered region, it 120 checks to see if it is the one at the head of the queue. If not, it 121 blocks on its RELEASE semaphore. */ 122 unsigned ordered_team_ids[]; 123 }; 124 125 /* This structure contains all of the thread-local data associated with 126 a thread team. This is the data that must be saved when a thread 127 encounters a nested PARALLEL construct. */ 128 129 struct gomp_team_state 130 { 131 /* This is the team of which the thread is currently a member. */ 132 struct gomp_team *team; 133 134 /* This is the work share construct which this thread is currently 135 processing. Recall that with NOWAIT, not all threads may be 136 processing the same construct. This value is NULL when there 137 is no construct being processed. */ 138 struct gomp_work_share *work_share; 139 140 /* This is the ID of this thread within the team. This value is 141 guaranteed to be between 0 and N-1, where N is the number of 142 threads in the team. */ 143 unsigned team_id; 144 145 /* The work share "generation" is a number that increases by one for 146 each work share construct encountered in the dynamic flow of the 147 program. It is used to find the control data for the work share 148 when encountering it for the first time. This particular number 149 reflects the generation of the work_share member of this struct. */ 150 unsigned work_share_generation; 151 152 /* For GFS_RUNTIME loops that resolved to GFS_STATIC, this is the 153 trip number through the loop. So first time a particular loop 154 is encountered this number is 0, the second time through the loop 155 is 1, etc. This is unused when the compiler knows in advance that 156 the loop is statically scheduled. */ 157 unsigned long static_trip; 158 }; 159 160 /* This structure describes a "team" of threads. These are the threads 161 that are spawned by a PARALLEL constructs, as well as the work sharing 162 constructs that the team encounters. */ 163 164 struct gomp_team 165 { 166 /* This lock protects access to the following work shares data structures. */ 167 gomp_mutex_t work_share_lock; 168 169 /* This is a dynamically sized array containing pointers to the control 170 structs for all "live" work share constructs. Here "live" means that 171 the construct has been encountered by at least one thread, and not 172 completed by all threads. */ 173 struct gomp_work_share **work_shares; 174 175 /* The work_shares array is indexed by "generation & generation_mask". 176 The mask will be 2**N - 1, where 2**N is the size of the array. */ 177 unsigned generation_mask; 178 179 /* These two values define the bounds of the elements of the work_shares 180 array that are currently in use. */ 181 unsigned oldest_live_gen; 182 unsigned num_live_gen; 183 184 /* This is the number of threads in the current team. */ 185 unsigned nthreads; 186 187 /* This is the saved team state that applied to a master thread before 188 the current thread was created. */ 189 struct gomp_team_state prev_ts; 190 191 /* This barrier is used for most synchronization of the team. */ 192 gomp_barrier_t barrier; 193 194 /* This semaphore should be used by the master thread instead of its 195 "native" semaphore in the thread structure. Required for nested 196 parallels, as the master is a member of two teams. */ 197 gomp_sem_t master_release; 198 199 /* This array contains pointers to the release semaphore of the threads 200 in the team. */ 201 gomp_sem_t *ordered_release[]; 202 }; 203 204 /* This structure contains all data that is private to libgomp and is 205 allocated per thread. */ 206 207 struct gomp_thread 208 { 209 /* This is the function that the thread should run upon launch. */ 210 void (*fn) (void *data); 211 void *data; 212 213 /* This is the current team state for this thread. The ts.team member 214 is NULL only if the thread is idle. */ 215 struct gomp_team_state ts; 216 217 /* This semaphore is used for ordered loops. */ 218 gomp_sem_t release; 219 }; 220 221 /* ... and here is that TLS data. */ 222 223 #ifdef HAVE_TLS 224 extern __thread struct gomp_thread gomp_tls_data; 225 static inline struct gomp_thread *gomp_thread (void) 226 { 227 return &gomp_tls_data; 228 } 229 #else 230 extern pthread_key_t gomp_tls_key; 231 static inline struct gomp_thread *gomp_thread (void) 232 { 233 return pthread_getspecific (gomp_tls_key); 234 } 235 #endif 236 237 /* These are the OpenMP 2.5 internal control variables described in 238 section 2.3. At least those that correspond to environment variables. */ 239 240 extern unsigned long gomp_nthreads_var; 241 extern bool gomp_dyn_var; 242 extern bool gomp_nest_var; 243 extern enum gomp_schedule_type gomp_run_sched_var; 244 extern unsigned long gomp_run_sched_chunk; 245 246 /* The attributes to be used during thread creation. */ 247 extern pthread_attr_t gomp_thread_attr; 248 249 /* Function prototypes. */ 250 251 /* alloc.c */ 252 253 extern void *gomp_malloc (size_t) __attribute__((malloc)); 254 extern void *gomp_malloc_cleared (size_t) __attribute__((malloc)); 255 extern void *gomp_realloc (void *, size_t); 256 257 /* Avoid conflicting prototypes of alloca() in system headers by using 258 GCC's builtin alloca(). */ 259 #define gomp_alloca(x) __builtin_alloca(x) 260 261 /* error.c */ 262 263 extern void gomp_error (const char *, ...) 264 __attribute__((format (printf, 1, 2))); 265 extern void gomp_fatal (const char *, ...) 266 __attribute__((noreturn, format (printf, 1, 2))); 267 268 /* iter.c */ 269 270 extern int gomp_iter_static_next (long *, long *); 271 extern bool gomp_iter_dynamic_next_locked (long *, long *); 272 extern bool gomp_iter_guided_next_locked (long *, long *); 273 274 #ifdef HAVE_SYNC_BUILTINS 275 extern bool gomp_iter_dynamic_next (long *, long *); 276 extern bool gomp_iter_guided_next (long *, long *); 277 #endif 278 279 /* ordered.c */ 280 281 extern void gomp_ordered_first (void); 282 extern void gomp_ordered_last (void); 283 extern void gomp_ordered_next (void); 284 extern void gomp_ordered_static_init (void); 285 extern void gomp_ordered_static_next (void); 286 extern void gomp_ordered_sync (void); 287 288 /* parallel.c */ 289 290 extern unsigned gomp_resolve_num_threads (unsigned); 291 292 /* proc.c (in config/) */ 293 294 extern void gomp_init_num_threads (void); 295 extern unsigned gomp_dynamic_max_threads (void); 296 297 /* team.c */ 298 299 extern void gomp_team_start (void (*) (void *), void *, unsigned, 300 struct gomp_work_share *); 301 extern void gomp_team_end (void); 302 303 /* work.c */ 304 305 extern struct gomp_work_share * gomp_new_work_share (bool, unsigned); 306 extern bool gomp_work_share_start (bool); 307 extern void gomp_work_share_end (void); 308 extern void gomp_work_share_end_nowait (void); 309 310 #ifdef HAVE_ATTRIBUTE_VISIBILITY 311 # pragma GCC visibility pop 312 #endif 313 314 /* Now that we're back to default visibility, include the globals. */ 315 #include "libgomp_g.h" 316 317 /* Include omp.h by parts. */ 318 #include "omp-lock.h" 319 #define _LIBGOMP_OMP_LOCK_DEFINED 1 320 #include "omp.h.in" 321 322 #ifdef HAVE_ATTRIBUTE_VISIBILITY 323 # define attribute_hidden __attribute__ ((visibility ("hidden"))) 324 #else 325 # define attribute_hidden 326 #endif 327 328 #ifdef HAVE_ATTRIBUTE_ALIAS 329 # define ialias(fn) \ 330 extern __typeof (fn) gomp_ialias_##fn \ 331 __attribute__ ((alias (#fn))) attribute_hidden; 332 #else 333 # define ialias(fn) 334 #endif 335 336 #endif /* LIBGOMP_H */ 337