1283010Spfg/* Copyright (C) 2005, 2007 Free Software Foundation, Inc.
2169695Skan   Contributed by Richard Henderson <rth@redhat.com>.
3169695Skan
4169695Skan   This file is part of the GNU OpenMP Library (libgomp).
5169695Skan
6169695Skan   Libgomp is free software; you can redistribute it and/or modify it
7169695Skan   under the terms of the GNU Lesser General Public License as published by
8169695Skan   the Free Software Foundation; either version 2.1 of the License, or
9169695Skan   (at your option) any later version.
10169695Skan
11169695Skan   Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
12169695Skan   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13169695Skan   FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
14169695Skan   more details.
15169695Skan
16169695Skan   You should have received a copy of the GNU Lesser General Public License
17169695Skan   along with libgomp; see the file COPYING.LIB.  If not, write to the
18169695Skan   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19169695Skan   MA 02110-1301, USA.  */
20169695Skan
21169695Skan/* As a special exception, if you link this library with other files, some
22169695Skan   of which are compiled with GCC, to produce an executable, this library
23169695Skan   does not by itself cause the resulting executable to be covered by the
24169695Skan   GNU General Public License.  This exception does not however invalidate
25169695Skan   any other reasons why the executable file might be covered by the GNU
26169695Skan   General Public License.  */
27169695Skan
28169695Skan/* This file contains data types and function declarations that are not
29169695Skan   part of the official OpenMP user interface.  There are declarations
30169695Skan   in here that are part of the GNU OpenMP ABI, in that the compiler is
31169695Skan   required to know about them and use them.
32169695Skan
33169695Skan   The convention is that the all caps prefix "GOMP" is used group items
34169695Skan   that are part of the external ABI, and the lower case prefix "gomp"
35169695Skan   is used group items that are completely private to the library.  */
36169695Skan
37169695Skan#ifndef LIBGOMP_H
38169695Skan#define LIBGOMP_H 1
39169695Skan
40169695Skan#include "config.h"
41169695Skan#include "gstdint.h"
42169695Skan
43169695Skan#include <pthread.h>
44169695Skan#include <stdbool.h>
45169695Skan
46169695Skan#ifdef HAVE_ATTRIBUTE_VISIBILITY
47169695Skan# pragma GCC visibility push(hidden)
48169695Skan#endif
49169695Skan
50169695Skan#include "sem.h"
51169695Skan#include "mutex.h"
52169695Skan#include "bar.h"
53169695Skan
54169695Skan
55169695Skan/* This structure contains the data to control one work-sharing construct,
56169695Skan   either a LOOP (FOR/DO) or a SECTIONS.  */
57169695Skan
58169695Skanenum gomp_schedule_type
59169695Skan{
60169695Skan  GFS_STATIC,
61169695Skan  GFS_DYNAMIC,
62169695Skan  GFS_GUIDED,
63169695Skan  GFS_RUNTIME
64169695Skan};
65169695Skan
66169695Skanstruct gomp_work_share
67169695Skan{
68169695Skan  /* This member records the SCHEDULE clause to be used for this construct.
69169695Skan     The user specification of "runtime" will already have been resolved.
70169695Skan     If this is a SECTIONS construct, this value will always be DYNAMIC.  */
71169695Skan  enum gomp_schedule_type sched;
72169695Skan
73169695Skan  /* This is the chunk_size argument to the SCHEDULE clause.  */
74169695Skan  long chunk_size;
75169695Skan
76169695Skan  /* This is the iteration end point.  If this is a SECTIONS construct,
77169695Skan     this is the number of contained sections.  */
78169695Skan  long end;
79169695Skan
80169695Skan  /* This is the iteration step.  If this is a SECTIONS construct, this
81169695Skan     is always 1.  */
82169695Skan  long incr;
83169695Skan
84169695Skan  /* This lock protects the update of the following members.  */
85169695Skan  gomp_mutex_t lock;
86169695Skan
87169695Skan  union {
88169695Skan    /* This is the next iteration value to be allocated.  In the case of
89169695Skan       GFS_STATIC loops, this the iteration start point and never changes.  */
90169695Skan    long next;
91169695Skan
92169695Skan    /* This is the returned data structure for SINGLE COPYPRIVATE.  */
93169695Skan    void *copyprivate;
94169695Skan  };
95169695Skan
96169695Skan  /* This is the count of the number of threads that have exited the work
97169695Skan     share construct.  If the construct was marked nowait, they have moved on
98169695Skan     to other work; otherwise they're blocked on a barrier.  The last member
99169695Skan     of the team to exit the work share construct must deallocate it.  */
100169695Skan  unsigned threads_completed;
101169695Skan
102169695Skan  /* This is the index into the circular queue ordered_team_ids of the
103169695Skan     current thread that's allowed into the ordered reason.  */
104169695Skan  unsigned ordered_cur;
105169695Skan
106169695Skan  /* This is the number of threads that have registered themselves in
107169695Skan     the circular queue ordered_team_ids.  */
108169695Skan  unsigned ordered_num_used;
109169695Skan
110169695Skan  /* This is the team_id of the currently acknoledged owner of the ordered
111169695Skan     section, or -1u if the ordered section has not been acknowledged by
112169695Skan     any thread.  This is distinguished from the thread that is *allowed*
113169695Skan     to take the section next.  */
114169695Skan  unsigned ordered_owner;
115169695Skan
116169695Skan  /* This is a circular queue that details which threads will be allowed
117169695Skan     into the ordered region and in which order.  When a thread allocates
118169695Skan     iterations on which it is going to work, it also registers itself at
119169695Skan     the end of the array.  When a thread reaches the ordered region, it
120169695Skan     checks to see if it is the one at the head of the queue.  If not, it
121169695Skan     blocks on its RELEASE semaphore.  */
122169695Skan  unsigned ordered_team_ids[];
123169695Skan};
124169695Skan
125169695Skan/* This structure contains all of the thread-local data associated with
126169695Skan   a thread team.  This is the data that must be saved when a thread
127169695Skan   encounters a nested PARALLEL construct.  */
128169695Skan
129169695Skanstruct gomp_team_state
130169695Skan{
131169695Skan  /* This is the team of which the thread is currently a member.  */
132169695Skan  struct gomp_team *team;
133169695Skan
134169695Skan  /* This is the work share construct which this thread is currently
135169695Skan     processing.  Recall that with NOWAIT, not all threads may be
136169695Skan     processing the same construct.  This value is NULL when there
137169695Skan     is no construct being processed.  */
138169695Skan  struct gomp_work_share *work_share;
139169695Skan
140169695Skan  /* This is the ID of this thread within the team.  This value is
141169695Skan     guaranteed to be between 0 and N-1, where N is the number of
142169695Skan     threads in the team.  */
143169695Skan  unsigned team_id;
144169695Skan
145169695Skan  /* The work share "generation" is a number that increases by one for
146169695Skan     each work share construct encountered in the dynamic flow of the
147169695Skan     program.  It is used to find the control data for the work share
148169695Skan     when encountering it for the first time.  This particular number
149169695Skan     reflects the generation of the work_share member of this struct.  */
150169695Skan  unsigned work_share_generation;
151169695Skan
152169695Skan  /* For GFS_RUNTIME loops that resolved to GFS_STATIC, this is the
153169695Skan     trip number through the loop.  So first time a particular loop
154169695Skan     is encountered this number is 0, the second time through the loop
155169695Skan     is 1, etc.  This is unused when the compiler knows in advance that
156169695Skan     the loop is statically scheduled.  */
157169695Skan  unsigned long static_trip;
158169695Skan};
159169695Skan
160169695Skan/* This structure describes a "team" of threads.  These are the threads
161169695Skan   that are spawned by a PARALLEL constructs, as well as the work sharing
162169695Skan   constructs that the team encounters.  */
163169695Skan
164169695Skanstruct gomp_team
165169695Skan{
166169695Skan  /* This lock protects access to the following work shares data structures.  */
167169695Skan  gomp_mutex_t work_share_lock;
168169695Skan
169169695Skan  /* This is a dynamically sized array containing pointers to the control
170169695Skan     structs for all "live" work share constructs.  Here "live" means that
171169695Skan     the construct has been encountered by at least one thread, and not
172169695Skan     completed by all threads.  */
173169695Skan  struct gomp_work_share **work_shares;
174169695Skan
175169695Skan  /* The work_shares array is indexed by "generation & generation_mask".
176169695Skan     The mask will be 2**N - 1, where 2**N is the size of the array.  */
177169695Skan  unsigned generation_mask;
178169695Skan
179169695Skan  /* These two values define the bounds of the elements of the work_shares
180169695Skan     array that are currently in use.  */
181169695Skan  unsigned oldest_live_gen;
182169695Skan  unsigned num_live_gen;
183169695Skan
184169695Skan  /* This is the number of threads in the current team.  */
185169695Skan  unsigned nthreads;
186169695Skan
187169695Skan  /* This is the saved team state that applied to a master thread before
188169695Skan     the current thread was created.  */
189169695Skan  struct gomp_team_state prev_ts;
190169695Skan
191169695Skan  /* This barrier is used for most synchronization of the team.  */
192169695Skan  gomp_barrier_t barrier;
193169695Skan
194169695Skan  /* This semaphore should be used by the master thread instead of its
195169695Skan     "native" semaphore in the thread structure.  Required for nested
196169695Skan     parallels, as the master is a member of two teams.  */
197169695Skan  gomp_sem_t master_release;
198169695Skan
199169695Skan  /* This array contains pointers to the release semaphore of the threads
200169695Skan     in the team.  */
201169695Skan  gomp_sem_t *ordered_release[];
202169695Skan};
203169695Skan
204169695Skan/* This structure contains all data that is private to libgomp and is
205169695Skan   allocated per thread.  */
206169695Skan
207169695Skanstruct gomp_thread
208169695Skan{
209169695Skan  /* This is the function that the thread should run upon launch.  */
210169695Skan  void (*fn) (void *data);
211169695Skan  void *data;
212169695Skan
213169695Skan  /* This is the current team state for this thread.  The ts.team member
214169695Skan     is NULL only if the thread is idle.  */
215169695Skan  struct gomp_team_state ts;
216169695Skan
217169695Skan  /* This semaphore is used for ordered loops.  */
218169695Skan  gomp_sem_t release;
219169695Skan};
220169695Skan
221169695Skan/* ... and here is that TLS data.  */
222169695Skan
223169695Skan#ifdef HAVE_TLS
224169695Skanextern __thread struct gomp_thread gomp_tls_data;
225169695Skanstatic inline struct gomp_thread *gomp_thread (void)
226169695Skan{
227169695Skan  return &gomp_tls_data;
228169695Skan}
229169695Skan#else
230169695Skanextern pthread_key_t gomp_tls_key;
231169695Skanstatic inline struct gomp_thread *gomp_thread (void)
232169695Skan{
233169695Skan  return pthread_getspecific (gomp_tls_key);
234169695Skan}
235169695Skan#endif
236169695Skan
237169695Skan/* These are the OpenMP 2.5 internal control variables described in
238169695Skan   section 2.3.  At least those that correspond to environment variables.  */
239169695Skan
240169695Skanextern unsigned long gomp_nthreads_var;
241169695Skanextern bool gomp_dyn_var;
242169695Skanextern bool gomp_nest_var;
243169695Skanextern enum gomp_schedule_type gomp_run_sched_var;
244169695Skanextern unsigned long gomp_run_sched_chunk;
245169695Skan
246169695Skan/* The attributes to be used during thread creation.  */
247169695Skanextern pthread_attr_t gomp_thread_attr;
248169695Skan
249283010Spfg/* Other variables.  */
250283010Spfg
251283010Spfgextern unsigned short *gomp_cpu_affinity;
252283010Spfgextern size_t gomp_cpu_affinity_len;
253283010Spfg
254169695Skan/* Function prototypes.  */
255169695Skan
256283010Spfg/* affinity.c */
257283010Spfg
258283010Spfgextern void gomp_init_affinity (void);
259283010Spfgextern void gomp_init_thread_affinity (pthread_attr_t *);
260283010Spfg
261169695Skan/* alloc.c */
262169695Skan
263169695Skanextern void *gomp_malloc (size_t) __attribute__((malloc));
264169695Skanextern void *gomp_malloc_cleared (size_t) __attribute__((malloc));
265169695Skanextern void *gomp_realloc (void *, size_t);
266169695Skan
267169695Skan/* Avoid conflicting prototypes of alloca() in system headers by using
268169695Skan   GCC's builtin alloca().  */
269169695Skan#define gomp_alloca(x)  __builtin_alloca(x)
270169695Skan
271169695Skan/* error.c */
272169695Skan
273169695Skanextern void gomp_error (const char *, ...)
274169695Skan	__attribute__((format (printf, 1, 2)));
275169695Skanextern void gomp_fatal (const char *, ...)
276169695Skan	__attribute__((noreturn, format (printf, 1, 2)));
277169695Skan
278169695Skan/* iter.c */
279169695Skan
280169695Skanextern int gomp_iter_static_next (long *, long *);
281169695Skanextern bool gomp_iter_dynamic_next_locked (long *, long *);
282169695Skanextern bool gomp_iter_guided_next_locked (long *, long *);
283169695Skan
284169695Skan#ifdef HAVE_SYNC_BUILTINS
285169695Skanextern bool gomp_iter_dynamic_next (long *, long *);
286169695Skanextern bool gomp_iter_guided_next (long *, long *);
287169695Skan#endif
288169695Skan
289169695Skan/* ordered.c */
290169695Skan
291169695Skanextern void gomp_ordered_first (void);
292169695Skanextern void gomp_ordered_last (void);
293169695Skanextern void gomp_ordered_next (void);
294169695Skanextern void gomp_ordered_static_init (void);
295169695Skanextern void gomp_ordered_static_next (void);
296169695Skanextern void gomp_ordered_sync (void);
297169695Skan
298169695Skan/* parallel.c */
299169695Skan
300169695Skanextern unsigned gomp_resolve_num_threads (unsigned);
301169695Skan
302169695Skan/* proc.c (in config/) */
303169695Skan
304169695Skanextern void gomp_init_num_threads (void);
305169695Skanextern unsigned gomp_dynamic_max_threads (void);
306169695Skan
307169695Skan/* team.c */
308169695Skan
309169695Skanextern void gomp_team_start (void (*) (void *), void *, unsigned,
310169695Skan			     struct gomp_work_share *);
311169695Skanextern void gomp_team_end (void);
312169695Skan
313169695Skan/* work.c */
314169695Skan
315169695Skanextern struct gomp_work_share * gomp_new_work_share (bool, unsigned);
316169695Skanextern bool gomp_work_share_start (bool);
317169695Skanextern void gomp_work_share_end (void);
318169695Skanextern void gomp_work_share_end_nowait (void);
319169695Skan
320169695Skan#ifdef HAVE_ATTRIBUTE_VISIBILITY
321169695Skan# pragma GCC visibility pop
322169695Skan#endif
323169695Skan
324169695Skan/* Now that we're back to default visibility, include the globals.  */
325169695Skan#include "libgomp_g.h"
326169695Skan
327169695Skan/* Include omp.h by parts.  */
328169695Skan#include "omp-lock.h"
329169695Skan#define _LIBGOMP_OMP_LOCK_DEFINED 1
330169695Skan#include "omp.h.in"
331169695Skan
332169695Skan#ifdef HAVE_ATTRIBUTE_VISIBILITY
333169695Skan# define attribute_hidden __attribute__ ((visibility ("hidden")))
334169695Skan#else
335169695Skan# define attribute_hidden
336169695Skan#endif
337169695Skan
338169695Skan#ifdef HAVE_ATTRIBUTE_ALIAS
339169695Skan# define ialias(fn) \
340169695Skan  extern __typeof (fn) gomp_ialias_##fn \
341169695Skan    __attribute__ ((alias (#fn))) attribute_hidden;
342169695Skan#else
343169695Skan# define ialias(fn)
344169695Skan#endif
345169695Skan
346169695Skan#endif /* LIBGOMP_H */
347