OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgomp/] [libgomp.h] - Blame information for rev 774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 735 jeremybenn
/* Copyright (C) 2005, 2007, 2008, 2009, 2010, 2011
2
   Free Software Foundation, Inc.
3
   Contributed by Richard Henderson <rth@redhat.com>.
4
 
5
   This file is part of the GNU OpenMP Library (libgomp).
6
 
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.
11
 
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.
16
 
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.
20
 
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/>.  */
25
 
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.
30
 
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.  */
34
 
35
#ifndef LIBGOMP_H 
36
#define LIBGOMP_H 1
37
 
38
#include "config.h"
39
#include "gstdint.h"
40
 
41
#include <pthread.h>
42
#include <stdbool.h>
43
 
44
#ifdef HAVE_ATTRIBUTE_VISIBILITY
45
# pragma GCC visibility push(hidden)
46
#endif
47
 
48
/* If we were a C++ library, we'd get this from <std/atomic>.  */
49
enum memmodel
50
{
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
57
};
58
 
59
#include "sem.h"
60
#include "mutex.h"
61
#include "bar.h"
62
#include "ptrlock.h"
63
 
64
 
65
/* This structure contains the data to control one work-sharing construct,
66
   either a LOOP (FOR/DO) or a SECTIONS.  */
67
 
68
enum gomp_schedule_type
69
{
70
  GFS_RUNTIME,
71
  GFS_STATIC,
72
  GFS_DYNAMIC,
73
  GFS_GUIDED,
74
  GFS_AUTO
75
};
76
 
77
struct gomp_work_share
78
{
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;
83
 
84
  int mode;
85
 
86
  union {
87
    struct {
88
      /* This is the chunk_size argument to the SCHEDULE clause.  */
89
      long chunk_size;
90
 
91
      /* This is the iteration end point.  If this is a SECTIONS construct,
92
         this is the number of contained sections.  */
93
      long end;
94
 
95
      /* This is the iteration step.  If this is a SECTIONS construct, this
96
         is always 1.  */
97
      long incr;
98
    };
99
 
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;
105
    };
106
  };
107
 
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;
115
 
116
  /* This is the number of threads that have registered themselves in
117
     the circular queue ordered_team_ids.  */
118
  unsigned ordered_num_used;
119
 
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;
125
 
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;
129
 
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;
133
 
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.  */
137
 
138
  /* This lock protects the update of the following members.  */
139
  gomp_mutex_t lock __attribute__((aligned (64)));
140
 
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;
146
 
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;
151
 
152
    /* The same, but with unsigned long long type.  */
153
    unsigned long long next_ull;
154
 
155
    /* This is the returned data structure for SINGLE COPYPRIVATE.  */
156
    void *copyprivate;
157
  };
158
 
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;
163
 
164
    /* gomp_work_share structs are chained in the free work share cache
165
       through this.  */
166
    struct gomp_work_share *next_free;
167
  };
168
 
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];
172
};
173
 
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.  */
177
 
178
struct gomp_team_state
179
{
180
  /* This is the team of which the thread is currently a member.  */
181
  struct gomp_team *team;
182
 
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;
187
 
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;
193
 
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;
198
 
199
  /* Nesting level.  */
200
  unsigned level;
201
 
202
  /* Active nesting level.  Only active parallel regions are counted.  */
203
  unsigned active_level;
204
 
205
#ifdef HAVE_SYNC_BUILTINS
206
  /* Number of single stmts encountered.  */
207
  unsigned long single_count;
208
#endif
209
 
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;
216
};
217
 
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.  */
222
 
223
struct gomp_task_icv
224
{
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;
230
};
231
 
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;
242
 
243
enum gomp_task_kind
244
{
245
  GOMP_TASK_IMPLICIT,
246
  GOMP_TASK_IFFALSE,
247
  GOMP_TASK_WAITING,
248
  GOMP_TASK_TIED
249
};
250
 
251
/* This structure describes a "task" to be run by a thread.  */
252
 
253
struct gomp_task
254
{
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;
269
};
270
 
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.  */
274
 
275
struct gomp_team
276
{
277
  /* This is the number of threads in the current team.  */
278
  unsigned nthreads;
279
 
280
  /* This is number of gomp_work_share structs that have been allocated
281
     as a block last time.  */
282
  unsigned work_share_chunk;
283
 
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;
287
 
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;
292
 
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;
296
 
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;
302
 
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;
309
 
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
318
 
319
  /* This barrier is used for most synchronization of the team.  */
320
  gomp_barrier_t barrier;
321
 
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];
325
 
326
  gomp_mutex_t task_lock;
327
  struct gomp_task *task_queue;
328
  int task_count;
329
  int task_running_count;
330
 
331
  /* This array contains structures for implicit tasks.  */
332
  struct gomp_task implicit_task[];
333
};
334
 
335
/* This structure contains all data that is private to libgomp and is
336
   allocated per thread.  */
337
 
338
struct gomp_thread
339
{
340
  /* This is the function that the thread should run upon launch.  */
341
  void (*fn) (void *data);
342
  void *data;
343
 
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;
347
 
348
  /* This is the task that the thread is currently executing.  */
349
  struct gomp_task *task;
350
 
351
  /* This semaphore is used for ordered loops.  */
352
  gomp_sem_t release;
353
 
354
  /* user pthread thread pool */
355
  struct gomp_thread_pool *thread_pool;
356
};
357
 
358
 
359
struct gomp_thread_pool
360
{
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;
367
 
368
  /* This barrier holds and releases threads waiting in threads.  */
369
  gomp_barrier_t threads_dock;
370
};
371
 
372
/* ... and here is that TLS data.  */
373
 
374
#ifdef HAVE_TLS
375
extern __thread struct gomp_thread gomp_tls_data;
376
static inline struct gomp_thread *gomp_thread (void)
377
{
378
  return &gomp_tls_data;
379
}
380
#else
381
extern pthread_key_t gomp_tls_key;
382
static inline struct gomp_thread *gomp_thread (void)
383
{
384
  return pthread_getspecific (gomp_tls_key);
385
}
386
#endif
387
 
388
extern struct gomp_task_icv *gomp_new_icv (void);
389
 
390
/* Here's how to access the current copy of the ICVs.  */
391
 
392
static inline struct gomp_task_icv *gomp_icv (bool write)
393
{
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;
401
}
402
 
403
/* The attributes to be used during thread creation.  */
404
extern pthread_attr_t gomp_thread_attr;
405
 
406
/* Other variables.  */
407
 
408
extern unsigned short *gomp_cpu_affinity;
409
extern size_t gomp_cpu_affinity_len;
410
 
411
/* Function prototypes.  */
412
 
413
/* affinity.c */
414
 
415
extern void gomp_init_affinity (void);
416
extern void gomp_init_thread_affinity (pthread_attr_t *);
417
 
418
/* alloc.c */
419
 
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);
423
 
424
/* Avoid conflicting prototypes of alloca() in system headers by using
425
   GCC's builtin alloca().  */
426
#define gomp_alloca(x)  __builtin_alloca(x)
427
 
428
/* error.c */
429
 
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)));
434
 
435
/* iter.c */
436
 
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 *);
440
 
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
445
 
446
/* iter_ull.c */
447
 
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 *);
454
 
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
461
 
462
/* ordered.c */
463
 
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);
470
 
471
/* parallel.c */
472
 
473
extern unsigned gomp_resolve_num_threads (unsigned, unsigned);
474
 
475
/* proc.c (in config/) */
476
 
477
extern void gomp_init_num_threads (void);
478
extern unsigned gomp_dynamic_max_threads (void);
479
 
480
/* task.c */
481
 
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);
486
 
487
static void inline
488
gomp_finish_task (struct gomp_task *task)
489
{
490
  gomp_sem_destroy (&task->taskwait_sem);
491
}
492
 
493
/* team.c */
494
 
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);
499
 
500
/* work.c */
501
 
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);
507
 
508
static inline void
509
gomp_work_share_init_done (void)
510
{
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);
514
}
515
 
516
#ifdef HAVE_ATTRIBUTE_VISIBILITY
517
# pragma GCC visibility pop
518
#endif
519
 
520
/* Now that we're back to default visibility, include the globals.  */
521
#include "libgomp_g.h"
522
 
523
/* Include omp.h by parts.  */
524
#include "omp-lock.h"
525
#define _LIBGOMP_OMP_LOCK_DEFINED 1
526
#include "omp.h.in"
527
 
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
535
 
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;
547
 
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;
558
 
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
576
 
577
#ifdef HAVE_ATTRIBUTE_VISIBILITY
578
# define attribute_hidden __attribute__ ((visibility ("hidden")))
579
#else
580
# define attribute_hidden
581
#endif
582
 
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
590
 
591
#endif /* LIBGOMP_H */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.