source: trunk/sys/libgomp/include/gomp/libgomp.h @ 347

Last change on this file since 347 was 1, checked in by alain, 8 years ago

First import

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