OSDN Git Service

2006-01-18 Richard Henderson <rth@redhat.com>
[pf3gnuchains/gcc-fork.git] / libgomp / libgomp.h
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
42 #include <pthread.h>
43 #include <stdbool.h>
44
45 #ifdef HAVE_ATTRIBUTE_VISIBILITY
46 # pragma GCC visibility push(hidden)
47 #endif
48
49 #include "sem.h"
50 #include "mutex.h"
51 #include "bar.h"
52
53
54 /* This structure contains the data to control one work-sharing construct,
55    either a LOOP (FOR/DO) or a SECTIONS.  */
56
57 enum gomp_schedule_type
58 {
59   GFS_STATIC,
60   GFS_DYNAMIC,
61   GFS_GUIDED,
62   GFS_RUNTIME
63 };
64
65 struct gomp_work_share
66 {
67   /* This member records the SCHEDULE clause to be used for this construct.
68      The user specification of "runtime" will already have been resolved.
69      If this is a SECTIONS construct, this value will always be DYNAMIC.  */
70   enum gomp_schedule_type sched;
71
72   /* This is the chunk_size argument to the SCHEDULE clause.  */
73   long chunk_size;
74
75   /* This is the iteration end point.  If this is a SECTIONS construct, 
76      this is the number of contained sections.  */
77   long end;
78
79   /* This is the iteration step.  If this is a SECTIONS construct, this
80      is always 1.  */
81   long incr;
82
83   /* This lock protects the update of the following members.  */
84   gomp_mutex_t lock;
85
86   union {
87     /* This is the next iteration value to be allocated.  In the case of
88        GFS_STATIC loops, this the iteration start point and never changes.  */
89     long next;
90
91     /* This is the returned data structure for SINGLE COPYPRIVATE.  */
92     void *copyprivate;
93   };
94
95   /* This is the count of the number of threads that have exited the work
96      share construct.  If the construct was marked nowait, they have moved on
97      to other work; otherwise they're blocked on a barrier.  The last member
98      of the team to exit the work share construct must deallocate it.  */
99   unsigned threads_completed;
100
101   /* This is the index into the circular queue ordered_team_ids of the 
102      current thread that's allowed into the ordered reason.  */
103   unsigned ordered_cur;
104
105   /* This is the number of threads that have registered themselves in
106      the circular queue ordered_team_ids.  */
107   unsigned ordered_num_used;
108
109   /* This is the team_id of the currently acknoledged owner of the ordered
110      section, or -1u if the ordered section has not been acknowledged by
111      any thread.  This is distinguished from the thread that is *allowed*
112      to take the section next.  */
113   unsigned ordered_owner;
114
115   /* This is a circular queue that details which threads will be allowed
116      into the ordered region and in which order.  When a thread allocates
117      iterations on which it is going to work, it also registers itself at
118      the end of the array.  When a thread reaches the ordered region, it
119      checks to see if it is the one at the head of the queue.  If not, it
120      blocks on its RELEASE semaphore.  */
121   unsigned ordered_team_ids[];
122 };
123
124 /* This structure contains all of the thread-local data associated with 
125    a thread team.  This is the data that must be saved when a thread
126    encounters a nested PARALLEL construct.  */
127
128 struct gomp_team_state
129 {
130   /* This is the team of which the thread is currently a member.  */
131   struct gomp_team *team;
132
133   /* This is the work share construct which this thread is currently
134      processing.  Recall that with NOWAIT, not all threads may be 
135      processing the same construct.  This value is NULL when there
136      is no construct being processed.  */
137   struct gomp_work_share *work_share;
138
139   /* This is the ID of this thread within the team.  This value is
140      guaranteed to be between 0 and N-1, where N is the number of
141      threads in the team.  */
142   unsigned team_id;
143
144   /* The work share "generation" is a number that increases by one for
145      each work share construct encountered in the dynamic flow of the
146      program.  It is used to find the control data for the work share
147      when encountering it for the first time.  This particular number
148      reflects the generation of the work_share member of this struct.  */
149   unsigned work_share_generation;
150
151   /* For GFS_RUNTIME loops that resolved to GFS_STATIC, this is the
152      trip number through the loop.  So first time a particular loop
153      is encountered this number is 0, the second time through the loop
154      is 1, etc.  This is unused when the compiler knows in advance that
155      the loop is statically scheduled.  */
156   unsigned long static_trip;
157 };
158
159 /* This structure describes a "team" of threads.  These are the threads
160    that are spawned by a PARALLEL constructs, as well as the work sharing
161    constructs that the team encounters.  */
162
163 struct gomp_team
164 {
165   /* This lock protects access to the following work shares data structures.  */
166   gomp_mutex_t work_share_lock;
167
168   /* This is a dynamically sized array containing pointers to the control
169      structs for all "live" work share constructs.  Here "live" means that
170      the construct has been encountered by at least one thread, and not
171      completed by all threads.  */
172   struct gomp_work_share **work_shares;
173
174   /* The work_shares array is indexed by "generation & generation_mask".
175      The mask will be 2**N - 1, where 2**N is the size of the array.  */
176   unsigned generation_mask;
177
178   /* These two values define the bounds of the elements of the work_shares
179      array that are currently in use.  */
180   unsigned oldest_live_gen;
181   unsigned num_live_gen;
182
183   /* This is the number of threads in the current team.  */
184   unsigned nthreads;
185
186   /* This is the saved team state that applied to a master thread before
187      the current thread was created.  */
188   struct gomp_team_state prev_ts;
189
190   /* This barrier is used for most synchronization of the team.  */
191   gomp_barrier_t barrier;
192
193   /* This semaphore should be used by the master thread instead of its
194      "native" semaphore in the thread structure.  Required for nested
195      parallels, as the master is a member of two teams.  */
196   gomp_sem_t master_release;
197
198   /* This array contains pointers to the release semaphore of the threads
199      in the team.  */
200   gomp_sem_t *ordered_release[];
201 };
202
203 /* This structure contains all data that is private to libgomp and is
204    allocated per thread.  */
205
206 struct gomp_thread
207 {
208   /* This is the function that the thread should run upon launch.  */
209   void (*fn) (void *data);
210   void *data;
211
212   /* This is the current team state for this thread.  The ts.team member
213      is NULL only if the thread is idle.  */
214   struct gomp_team_state ts;
215
216   /* This semaphore is used for ordered loops.  */
217   gomp_sem_t release;
218 };
219
220 /* ... and here is that TLS data.  */
221
222 #ifdef HAVE_TLS
223 extern __thread struct gomp_thread gomp_tls_data;
224 static inline struct gomp_thread *gomp_thread (void)
225 {
226   return &gomp_tls_data;
227 }
228 #else
229 extern pthread_key_t gomp_tls_key;
230 static inline struct gomp_thread *gomp_thread (void)
231 {
232   return pthread_getspecific (gomp_tls_key);
233 }
234 #endif
235
236 /* These are the OpenMP 2.5 internal control variables described in
237    section 2.3.  At least those that correspond to environment variables.  */
238
239 extern unsigned gomp_nthreads_var;
240 extern bool gomp_dyn_var;
241 extern bool gomp_nest_var;
242 extern enum gomp_schedule_type gomp_run_sched_var;
243 extern unsigned gomp_run_sched_chunk;
244
245 /* Function prototypes.  */
246
247 /* alloc.c */
248
249 extern void *gomp_malloc (size_t) __attribute__((malloc));
250 extern void *gomp_malloc_cleared (size_t) __attribute__((malloc));
251 extern void *gomp_realloc (void *, size_t);
252
253 /* error.c */
254
255 extern void gomp_error (const char *, ...)
256         __attribute__((format (printf, 1, 2)));
257 extern void gomp_fatal (const char *, ...)
258         __attribute__((noreturn, format (printf, 1, 2)));
259
260 /* iter.c */
261
262 extern int gomp_iter_static_next (long *, long *);
263 extern bool gomp_iter_dynamic_next_locked (long *, long *);
264 extern bool gomp_iter_guided_next_locked (long *, long *);
265
266 #ifdef HAVE_SYNC_BUILTINS
267 extern bool gomp_iter_dynamic_next (long *, long *);
268 extern bool gomp_iter_guided_next (long *, long *);
269 #endif
270
271 /* ordered.c */
272
273 extern void gomp_ordered_first (void);
274 extern void gomp_ordered_last (void);
275 extern void gomp_ordered_next (void);
276 extern void gomp_ordered_static_init (void);
277 extern void gomp_ordered_static_next (void);
278 extern void gomp_ordered_sync (void);
279
280 /* parallel.c */
281
282 extern unsigned gomp_resolve_num_threads (unsigned);
283
284 /* proc.c (in config/) */
285
286 extern void gomp_init_num_threads (void);
287 extern unsigned gomp_dynamic_max_threads (void);
288
289 /* team.c */
290
291 extern void gomp_team_start (void (*) (void *), void *, unsigned,
292                              struct gomp_work_share *);
293 extern void gomp_team_end (void);
294
295 /* work.c */
296
297 extern struct gomp_work_share * gomp_new_work_share (bool, unsigned);
298 extern bool gomp_work_share_start (bool);
299 extern void gomp_work_share_end (void);
300 extern void gomp_work_share_end_nowait (void);
301
302 #ifdef HAVE_ATTRIBUTE_VISIBILITY
303 # pragma GCC visibility pop
304 #endif
305
306 /* Now that we're back to default visibility, include the globals.  */
307 #include "libgomp_g.h"
308
309 /* Include omp.h by parts.  */
310 #include "omp-lock.h"
311 #define _LIBGOMP_OMP_LOCK_DEFINED 1
312 #include "omp.h.in"
313
314 #ifdef HAVE_ATTRIBUTE_VISIBILITY
315 # define attribute_hidden __attribute__ ((visibility ("hidden")))
316 #else
317 # define attribute_hidden
318 #endif
319
320 #ifdef HAVE_ATTRIBUTE_ALIAS
321 # define ialias(fn) \
322   extern __typeof (fn) gomp_ialias_##fn \
323     __attribute__ ((alias (#fn))) attribute_hidden;
324 #else
325 # define ialias(fn)
326 #endif
327
328 #endif /* LIBGOMP_H */