kernel - Fix TRIM bugs in UFS
[dragonfly.git] / contrib / gcc-4.7 / libgomp / libgomp.h
blob2c9c0716cd5300c2b79045ade307d0739cb27fb7
1 /* Copyright (C) 2005, 2007, 2008, 2009, 2010, 2011
2 Free Software Foundation, Inc.
3 Contributed by Richard Henderson <rth@redhat.com>.
5 This file is part of the GNU OpenMP Library (libgomp).
7 Libgomp is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 more details.
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
26 /* This file contains data types and function declarations that are not
27 part of the official OpenMP user interface. There are declarations
28 in here that are part of the GNU OpenMP ABI, in that the compiler is
29 required to know about them and use them.
31 The convention is that the all caps prefix "GOMP" is used group items
32 that are part of the external ABI, and the lower case prefix "gomp"
33 is used group items that are completely private to the library. */
35 #ifndef LIBGOMP_H
36 #define LIBGOMP_H 1
38 #include "config.h"
39 #include "gstdint.h"
41 #include <pthread.h>
42 #include <stdbool.h>
44 #ifdef HAVE_ATTRIBUTE_VISIBILITY
45 # pragma GCC visibility push(hidden)
46 #endif
48 /* If we were a C++ library, we'd get this from <std/atomic>. */
49 enum memmodel
51 MEMMODEL_RELAXED = 0,
52 MEMMODEL_CONSUME = 1,
53 MEMMODEL_ACQUIRE = 2,
54 MEMMODEL_RELEASE = 3,
55 MEMMODEL_ACQ_REL = 4,
56 MEMMODEL_SEQ_CST = 5
59 #include "sem.h"
60 #include "mutex.h"
61 #include "bar.h"
62 #include "ptrlock.h"
65 /* This structure contains the data to control one work-sharing construct,
66 either a LOOP (FOR/DO) or a SECTIONS. */
68 enum gomp_schedule_type
70 GFS_RUNTIME,
71 GFS_STATIC,
72 GFS_DYNAMIC,
73 GFS_GUIDED,
74 GFS_AUTO
77 struct gomp_work_share
79 /* This member records the SCHEDULE clause to be used for this construct.
80 The user specification of "runtime" will already have been resolved.
81 If this is a SECTIONS construct, this value will always be DYNAMIC. */
82 enum gomp_schedule_type sched;
84 int mode;
86 union {
87 struct {
88 /* This is the chunk_size argument to the SCHEDULE clause. */
89 long chunk_size;
91 /* This is the iteration end point. If this is a SECTIONS construct,
92 this is the number of contained sections. */
93 long end;
95 /* This is the iteration step. If this is a SECTIONS construct, this
96 is always 1. */
97 long incr;
100 struct {
101 /* The same as above, but for the unsigned long long loop variants. */
102 unsigned long long chunk_size_ull;
103 unsigned long long end_ull;
104 unsigned long long incr_ull;
108 /* This is a circular queue that details which threads will be allowed
109 into the ordered region and in which order. When a thread allocates
110 iterations on which it is going to work, it also registers itself at
111 the end of the array. When a thread reaches the ordered region, it
112 checks to see if it is the one at the head of the queue. If not, it
113 blocks on its RELEASE semaphore. */
114 unsigned *ordered_team_ids;
116 /* This is the number of threads that have registered themselves in
117 the circular queue ordered_team_ids. */
118 unsigned ordered_num_used;
120 /* This is the team_id of the currently acknowledged owner of the ordered
121 section, or -1u if the ordered section has not been acknowledged by
122 any thread. This is distinguished from the thread that is *allowed*
123 to take the section next. */
124 unsigned ordered_owner;
126 /* This is the index into the circular queue ordered_team_ids of the
127 current thread that's allowed into the ordered reason. */
128 unsigned ordered_cur;
130 /* This is a chain of allocated gomp_work_share blocks, valid only
131 in the first gomp_work_share struct in the block. */
132 struct gomp_work_share *next_alloc;
134 /* The above fields are written once during workshare initialization,
135 or related to ordered worksharing. Make sure the following fields
136 are in a different cache line. */
138 /* This lock protects the update of the following members. */
139 gomp_mutex_t lock __attribute__((aligned (64)));
141 /* This is the count of the number of threads that have exited the work
142 share construct. If the construct was marked nowait, they have moved on
143 to other work; otherwise they're blocked on a barrier. The last member
144 of the team to exit the work share construct must deallocate it. */
145 unsigned threads_completed;
147 union {
148 /* This is the next iteration value to be allocated. In the case of
149 GFS_STATIC loops, this the iteration start point and never changes. */
150 long next;
152 /* The same, but with unsigned long long type. */
153 unsigned long long next_ull;
155 /* This is the returned data structure for SINGLE COPYPRIVATE. */
156 void *copyprivate;
159 union {
160 /* Link to gomp_work_share struct for next work sharing construct
161 encountered after this one. */
162 gomp_ptrlock_t next_ws;
164 /* gomp_work_share structs are chained in the free work share cache
165 through this. */
166 struct gomp_work_share *next_free;
169 /* If only few threads are in the team, ordered_team_ids can point
170 to this array which fills the padding at the end of this struct. */
171 unsigned inline_ordered_team_ids[0];
174 /* This structure contains all of the thread-local data associated with
175 a thread team. This is the data that must be saved when a thread
176 encounters a nested PARALLEL construct. */
178 struct gomp_team_state
180 /* This is the team of which the thread is currently a member. */
181 struct gomp_team *team;
183 /* This is the work share construct which this thread is currently
184 processing. Recall that with NOWAIT, not all threads may be
185 processing the same construct. */
186 struct gomp_work_share *work_share;
188 /* This is the previous work share construct or NULL if there wasn't any.
189 When all threads are done with the current work sharing construct,
190 the previous one can be freed. The current one can't, as its
191 next_ws field is used. */
192 struct gomp_work_share *last_work_share;
194 /* This is the ID of this thread within the team. This value is
195 guaranteed to be between 0 and N-1, where N is the number of
196 threads in the team. */
197 unsigned team_id;
199 /* Nesting level. */
200 unsigned level;
202 /* Active nesting level. Only active parallel regions are counted. */
203 unsigned active_level;
205 #ifdef HAVE_SYNC_BUILTINS
206 /* Number of single stmts encountered. */
207 unsigned long single_count;
208 #endif
210 /* For GFS_RUNTIME loops that resolved to GFS_STATIC, this is the
211 trip number through the loop. So first time a particular loop
212 is encountered this number is 0, the second time through the loop
213 is 1, etc. This is unused when the compiler knows in advance that
214 the loop is statically scheduled. */
215 unsigned long static_trip;
218 /* These are the OpenMP 3.0 Internal Control Variables described in
219 section 2.3.1. Those described as having one copy per task are
220 stored within the structure; those described as having one copy
221 for the whole program are (naturally) global variables. */
223 struct gomp_task_icv
225 unsigned long nthreads_var;
226 enum gomp_schedule_type run_sched_var;
227 int run_sched_modifier;
228 bool dyn_var;
229 bool nest_var;
232 extern struct gomp_task_icv gomp_global_icv;
233 extern unsigned long gomp_thread_limit_var;
234 extern unsigned long gomp_remaining_threads_count;
235 #ifndef HAVE_SYNC_BUILTINS
236 extern gomp_mutex_t gomp_remaining_threads_lock;
237 #endif
238 extern unsigned long gomp_max_active_levels_var;
239 extern unsigned long long gomp_spin_count_var, gomp_throttled_spin_count_var;
240 extern unsigned long gomp_available_cpus, gomp_managed_threads;
241 extern unsigned long *gomp_nthreads_var_list, gomp_nthreads_var_list_len;
243 enum gomp_task_kind
245 GOMP_TASK_IMPLICIT,
246 GOMP_TASK_IFFALSE,
247 GOMP_TASK_WAITING,
248 GOMP_TASK_TIED
251 /* This structure describes a "task" to be run by a thread. */
253 struct gomp_task
255 struct gomp_task *parent;
256 struct gomp_task *children;
257 struct gomp_task *next_child;
258 struct gomp_task *prev_child;
259 struct gomp_task *next_queue;
260 struct gomp_task *prev_queue;
261 struct gomp_task_icv icv;
262 void (*fn) (void *);
263 void *fn_data;
264 enum gomp_task_kind kind;
265 bool in_taskwait;
266 bool in_tied_task;
267 bool final_task;
268 gomp_sem_t taskwait_sem;
271 /* This structure describes a "team" of threads. These are the threads
272 that are spawned by a PARALLEL constructs, as well as the work sharing
273 constructs that the team encounters. */
275 struct gomp_team
277 /* This is the number of threads in the current team. */
278 unsigned nthreads;
280 /* This is number of gomp_work_share structs that have been allocated
281 as a block last time. */
282 unsigned work_share_chunk;
284 /* This is the saved team state that applied to a master thread before
285 the current thread was created. */
286 struct gomp_team_state prev_ts;
288 /* This semaphore should be used by the master thread instead of its
289 "native" semaphore in the thread structure. Required for nested
290 parallels, as the master is a member of two teams. */
291 gomp_sem_t master_release;
293 /* This points to an array with pointers to the release semaphore
294 of the threads in the team. */
295 gomp_sem_t **ordered_release;
297 /* List of gomp_work_share structs chained through next_free fields.
298 This is populated and taken off only by the first thread in the
299 team encountering a new work sharing construct, in a critical
300 section. */
301 struct gomp_work_share *work_share_list_alloc;
303 /* List of gomp_work_share structs freed by free_work_share. New
304 entries are atomically added to the start of the list, and
305 alloc_work_share can safely only move all but the first entry
306 to work_share_list alloc, as free_work_share can happen concurrently
307 with alloc_work_share. */
308 struct gomp_work_share *work_share_list_free;
310 #ifdef HAVE_SYNC_BUILTINS
311 /* Number of simple single regions encountered by threads in this
312 team. */
313 unsigned long single_count;
314 #else
315 /* Mutex protecting addition of workshares to work_share_list_free. */
316 gomp_mutex_t work_share_list_free_lock;
317 #endif
319 /* This barrier is used for most synchronization of the team. */
320 gomp_barrier_t barrier;
322 /* Initial work shares, to avoid allocating any gomp_work_share
323 structs in the common case. */
324 struct gomp_work_share work_shares[8];
326 gomp_mutex_t task_lock;
327 struct gomp_task *task_queue;
328 int task_count;
329 int task_running_count;
331 /* This array contains structures for implicit tasks. */
332 struct gomp_task implicit_task[];
335 /* This structure contains all data that is private to libgomp and is
336 allocated per thread. */
338 struct gomp_thread
340 /* This is the function that the thread should run upon launch. */
341 void (*fn) (void *data);
342 void *data;
344 /* This is the current team state for this thread. The ts.team member
345 is NULL only if the thread is idle. */
346 struct gomp_team_state ts;
348 /* This is the task that the thread is currently executing. */
349 struct gomp_task *task;
351 /* This semaphore is used for ordered loops. */
352 gomp_sem_t release;
354 /* user pthread thread pool */
355 struct gomp_thread_pool *thread_pool;
359 struct gomp_thread_pool
361 /* This array manages threads spawned from the top level, which will
362 return to the idle loop once the current PARALLEL construct ends. */
363 struct gomp_thread **threads;
364 unsigned threads_size;
365 unsigned threads_used;
366 struct gomp_team *last_team;
368 /* This barrier holds and releases threads waiting in threads. */
369 gomp_barrier_t threads_dock;
372 /* ... and here is that TLS data. */
374 #ifdef HAVE_TLS
375 extern __thread struct gomp_thread gomp_tls_data;
376 static inline struct gomp_thread *gomp_thread (void)
378 return &gomp_tls_data;
380 #else
381 extern pthread_key_t gomp_tls_key;
382 static inline struct gomp_thread *gomp_thread (void)
384 return pthread_getspecific (gomp_tls_key);
386 #endif
388 extern struct gomp_task_icv *gomp_new_icv (void);
390 /* Here's how to access the current copy of the ICVs. */
392 static inline struct gomp_task_icv *gomp_icv (bool write)
394 struct gomp_task *task = gomp_thread ()->task;
395 if (task)
396 return &task->icv;
397 else if (write)
398 return gomp_new_icv ();
399 else
400 return &gomp_global_icv;
403 /* The attributes to be used during thread creation. */
404 extern pthread_attr_t gomp_thread_attr;
406 /* Other variables. */
408 extern unsigned short *gomp_cpu_affinity;
409 extern size_t gomp_cpu_affinity_len;
411 /* Function prototypes. */
413 /* affinity.c */
415 extern void gomp_init_affinity (void);
416 extern void gomp_init_thread_affinity (pthread_attr_t *);
418 /* alloc.c */
420 extern void *gomp_malloc (size_t) __attribute__((malloc));
421 extern void *gomp_malloc_cleared (size_t) __attribute__((malloc));
422 extern void *gomp_realloc (void *, size_t);
424 /* Avoid conflicting prototypes of alloca() in system headers by using
425 GCC's builtin alloca(). */
426 #define gomp_alloca(x) __builtin_alloca(x)
428 /* error.c */
430 extern void gomp_error (const char *, ...)
431 __attribute__((format (printf, 1, 2)));
432 extern void gomp_fatal (const char *, ...)
433 __attribute__((noreturn, format (printf, 1, 2)));
435 /* iter.c */
437 extern int gomp_iter_static_next (long *, long *);
438 extern bool gomp_iter_dynamic_next_locked (long *, long *);
439 extern bool gomp_iter_guided_next_locked (long *, long *);
441 #ifdef HAVE_SYNC_BUILTINS
442 extern bool gomp_iter_dynamic_next (long *, long *);
443 extern bool gomp_iter_guided_next (long *, long *);
444 #endif
446 /* iter_ull.c */
448 extern int gomp_iter_ull_static_next (unsigned long long *,
449 unsigned long long *);
450 extern bool gomp_iter_ull_dynamic_next_locked (unsigned long long *,
451 unsigned long long *);
452 extern bool gomp_iter_ull_guided_next_locked (unsigned long long *,
453 unsigned long long *);
455 #if defined HAVE_SYNC_BUILTINS && defined __LP64__
456 extern bool gomp_iter_ull_dynamic_next (unsigned long long *,
457 unsigned long long *);
458 extern bool gomp_iter_ull_guided_next (unsigned long long *,
459 unsigned long long *);
460 #endif
462 /* ordered.c */
464 extern void gomp_ordered_first (void);
465 extern void gomp_ordered_last (void);
466 extern void gomp_ordered_next (void);
467 extern void gomp_ordered_static_init (void);
468 extern void gomp_ordered_static_next (void);
469 extern void gomp_ordered_sync (void);
471 /* parallel.c */
473 extern unsigned gomp_resolve_num_threads (unsigned, unsigned);
475 /* proc.c (in config/) */
477 extern void gomp_init_num_threads (void);
478 extern unsigned gomp_dynamic_max_threads (void);
480 /* task.c */
482 extern void gomp_init_task (struct gomp_task *, struct gomp_task *,
483 struct gomp_task_icv *);
484 extern void gomp_end_task (void);
485 extern void gomp_barrier_handle_tasks (gomp_barrier_state_t);
487 static void inline
488 gomp_finish_task (struct gomp_task *task)
490 gomp_sem_destroy (&task->taskwait_sem);
493 /* team.c */
495 extern struct gomp_team *gomp_new_team (unsigned);
496 extern void gomp_team_start (void (*) (void *), void *, unsigned,
497 struct gomp_team *);
498 extern void gomp_team_end (void);
500 /* work.c */
502 extern void gomp_init_work_share (struct gomp_work_share *, bool, unsigned);
503 extern void gomp_fini_work_share (struct gomp_work_share *);
504 extern bool gomp_work_share_start (bool);
505 extern void gomp_work_share_end (void);
506 extern void gomp_work_share_end_nowait (void);
508 static inline void
509 gomp_work_share_init_done (void)
511 struct gomp_thread *thr = gomp_thread ();
512 if (__builtin_expect (thr->ts.last_work_share != NULL, 1))
513 gomp_ptrlock_set (&thr->ts.last_work_share->next_ws, thr->ts.work_share);
516 #ifdef HAVE_ATTRIBUTE_VISIBILITY
517 # pragma GCC visibility pop
518 #endif
520 /* Now that we're back to default visibility, include the globals. */
521 #include "libgomp_g.h"
523 /* Include omp.h by parts. */
524 #include "omp-lock.h"
525 #define _LIBGOMP_OMP_LOCK_DEFINED 1
526 #include "omp.h.in"
528 #if !defined (HAVE_ATTRIBUTE_VISIBILITY) \
529 || !defined (HAVE_ATTRIBUTE_ALIAS) \
530 || !defined (HAVE_AS_SYMVER_DIRECTIVE) \
531 || !defined (PIC) \
532 || !defined (HAVE_SYMVER_SYMBOL_RENAMING_RUNTIME_SUPPORT)
533 # undef LIBGOMP_GNU_SYMBOL_VERSIONING
534 #endif
536 #ifdef LIBGOMP_GNU_SYMBOL_VERSIONING
537 extern void gomp_init_lock_30 (omp_lock_t *) __GOMP_NOTHROW;
538 extern void gomp_destroy_lock_30 (omp_lock_t *) __GOMP_NOTHROW;
539 extern void gomp_set_lock_30 (omp_lock_t *) __GOMP_NOTHROW;
540 extern void gomp_unset_lock_30 (omp_lock_t *) __GOMP_NOTHROW;
541 extern int gomp_test_lock_30 (omp_lock_t *) __GOMP_NOTHROW;
542 extern void gomp_init_nest_lock_30 (omp_nest_lock_t *) __GOMP_NOTHROW;
543 extern void gomp_destroy_nest_lock_30 (omp_nest_lock_t *) __GOMP_NOTHROW;
544 extern void gomp_set_nest_lock_30 (omp_nest_lock_t *) __GOMP_NOTHROW;
545 extern void gomp_unset_nest_lock_30 (omp_nest_lock_t *) __GOMP_NOTHROW;
546 extern int gomp_test_nest_lock_30 (omp_nest_lock_t *) __GOMP_NOTHROW;
548 extern void gomp_init_lock_25 (omp_lock_25_t *) __GOMP_NOTHROW;
549 extern void gomp_destroy_lock_25 (omp_lock_25_t *) __GOMP_NOTHROW;
550 extern void gomp_set_lock_25 (omp_lock_25_t *) __GOMP_NOTHROW;
551 extern void gomp_unset_lock_25 (omp_lock_25_t *) __GOMP_NOTHROW;
552 extern int gomp_test_lock_25 (omp_lock_25_t *) __GOMP_NOTHROW;
553 extern void gomp_init_nest_lock_25 (omp_nest_lock_25_t *) __GOMP_NOTHROW;
554 extern void gomp_destroy_nest_lock_25 (omp_nest_lock_25_t *) __GOMP_NOTHROW;
555 extern void gomp_set_nest_lock_25 (omp_nest_lock_25_t *) __GOMP_NOTHROW;
556 extern void gomp_unset_nest_lock_25 (omp_nest_lock_25_t *) __GOMP_NOTHROW;
557 extern int gomp_test_nest_lock_25 (omp_nest_lock_25_t *) __GOMP_NOTHROW;
559 # define strong_alias(fn, al) \
560 extern __typeof (fn) al __attribute__ ((alias (#fn)));
561 # define omp_lock_symver(fn) \
562 __asm (".symver g" #fn "_30, " #fn "@@OMP_3.0"); \
563 __asm (".symver g" #fn "_25, " #fn "@OMP_1.0");
564 #else
565 # define gomp_init_lock_30 omp_init_lock
566 # define gomp_destroy_lock_30 omp_destroy_lock
567 # define gomp_set_lock_30 omp_set_lock
568 # define gomp_unset_lock_30 omp_unset_lock
569 # define gomp_test_lock_30 omp_test_lock
570 # define gomp_init_nest_lock_30 omp_init_nest_lock
571 # define gomp_destroy_nest_lock_30 omp_destroy_nest_lock
572 # define gomp_set_nest_lock_30 omp_set_nest_lock
573 # define gomp_unset_nest_lock_30 omp_unset_nest_lock
574 # define gomp_test_nest_lock_30 omp_test_nest_lock
575 #endif
577 #ifdef HAVE_ATTRIBUTE_VISIBILITY
578 # define attribute_hidden __attribute__ ((visibility ("hidden")))
579 #else
580 # define attribute_hidden
581 #endif
583 #ifdef HAVE_ATTRIBUTE_ALIAS
584 # define ialias(fn) \
585 extern __typeof (fn) gomp_ialias_##fn \
586 __attribute__ ((alias (#fn))) attribute_hidden;
587 #else
588 # define ialias(fn)
589 #endif
591 #endif /* LIBGOMP_H */