00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifndef LIBGOMP_H
00035 #define LIBGOMP_H 1
00036
00037 #include "config.h"
00038 #include "gstdint.h"
00039
00040 #include <pthread.h>
00041 #include <stdbool.h>
00042
00043 #ifdef HAVE_ATTRIBUTE_VISIBILITY
00044 # pragma GCC visibility push(hidden)
00045 #endif
00046
00047 #include "sem.h"
00048 #include "mutex.h"
00049 #include "bar.h"
00050 #include "ptrlock.h"
00051
00052
00053
00054
00055
00056 enum gomp_schedule_type
00057 {
00058 GFS_RUNTIME,
00059 GFS_STATIC,
00060 GFS_DYNAMIC,
00061 GFS_GUIDED,
00062 GFS_AUTO
00063 };
00064
00065 struct gomp_work_share
00066 {
00067
00068
00069
00070 enum gomp_schedule_type sched;
00071
00072 int mode;
00073
00074 union {
00075 struct {
00076
00077 long chunk_size;
00078
00079
00080
00081 long end;
00082
00083
00084
00085 long incr;
00086 };
00087
00088 struct {
00089
00090 unsigned long long chunk_size_ull;
00091 unsigned long long end_ull;
00092 unsigned long long incr_ull;
00093 };
00094 };
00095
00096
00097
00098
00099
00100
00101
00102 unsigned *ordered_team_ids;
00103
00104
00105
00106 unsigned ordered_num_used;
00107
00108
00109
00110
00111
00112 unsigned ordered_owner;
00113
00114
00115
00116 unsigned ordered_cur;
00117
00118
00119
00120 struct gomp_work_share *next_alloc;
00121
00122
00123
00124
00125
00126
00127 gomp_mutex_t lock __attribute__((aligned (64)));
00128
00129
00130
00131
00132
00133 unsigned threads_completed;
00134
00135 union {
00136
00137
00138 long next;
00139
00140
00141 unsigned long long next_ull;
00142
00143
00144 void *copyprivate;
00145 };
00146
00147 union {
00148
00149
00150 gomp_ptrlock_t next_ws;
00151
00152
00153
00154 struct gomp_work_share *next_free;
00155 };
00156
00157
00158
00159 unsigned inline_ordered_team_ids[0];
00160 };
00161
00162
00163
00164
00165
00166 struct gomp_team_state
00167 {
00168
00169 struct gomp_team *team;
00170
00171
00172
00173
00174 struct gomp_work_share *work_share;
00175
00176
00177
00178
00179
00180 struct gomp_work_share *last_work_share;
00181
00182
00183
00184
00185 unsigned team_id;
00186
00187
00188 unsigned level;
00189
00190
00191 unsigned active_level;
00192
00193 #ifdef HAVE_SYNC_BUILTINS
00194
00195 unsigned long single_count;
00196 #endif
00197
00198
00199
00200
00201
00202
00203 unsigned long static_trip;
00204 };
00205
00206
00207
00208
00209
00210
00211 struct gomp_task_icv
00212 {
00213 unsigned long nthreads_var;
00214 enum gomp_schedule_type run_sched_var;
00215 int run_sched_modifier;
00216 bool dyn_var;
00217 bool nest_var;
00218 };
00219
00220 extern struct gomp_task_icv gomp_global_icv;
00221 extern unsigned long gomp_thread_limit_var;
00222 extern unsigned long gomp_remaining_threads_count;
00223 #ifndef HAVE_SYNC_BUILTINS
00224 extern gomp_mutex_t gomp_remaining_threads_lock;
00225 #endif
00226 extern unsigned long gomp_max_active_levels_var;
00227 extern unsigned long long gomp_spin_count_var, gomp_throttled_spin_count_var;
00228 extern unsigned long gomp_available_cpus, gomp_managed_threads;
00229
00230 enum gomp_task_kind
00231 {
00232 GOMP_TASK_IMPLICIT,
00233 GOMP_TASK_IFFALSE,
00234 GOMP_TASK_WAITING,
00235 GOMP_TASK_TIED
00236 };
00237
00238
00239
00240 struct gomp_task
00241 {
00242 struct gomp_task *parent;
00243 struct gomp_task *children;
00244 struct gomp_task *next_child;
00245 struct gomp_task *prev_child;
00246 struct gomp_task *next_queue;
00247 struct gomp_task *prev_queue;
00248 struct gomp_task_icv icv;
00249 void (*fn) (void *);
00250 void *fn_data;
00251 enum gomp_task_kind kind;
00252 bool in_taskwait;
00253 bool in_tied_task;
00254 gomp_sem_t taskwait_sem;
00255 };
00256
00257
00258
00259
00260
00261 struct gomp_team
00262 {
00263
00264 unsigned nthreads;
00265
00266
00267
00268 unsigned work_share_chunk;
00269
00270
00271
00272 struct gomp_team_state prev_ts;
00273
00274
00275
00276
00277 gomp_sem_t master_release;
00278
00279
00280
00281 gomp_sem_t **ordered_release;
00282
00283
00284
00285
00286
00287 struct gomp_work_share *work_share_list_alloc;
00288
00289
00290
00291
00292
00293
00294 struct gomp_work_share *work_share_list_free;
00295
00296 #ifdef HAVE_SYNC_BUILTINS
00297
00298
00299 unsigned long single_count;
00300 #else
00301
00302 gomp_mutex_t work_share_list_free_lock;
00303 #endif
00304
00305
00306 gomp_barrier_t barrier;
00307
00308
00309
00310 struct gomp_work_share work_shares[8];
00311
00312 gomp_mutex_t task_lock;
00313 struct gomp_task *task_queue;
00314 int task_count;
00315 int task_running_count;
00316
00317
00318 struct gomp_task implicit_task[];
00319 };
00320
00321
00322
00323
00324 struct gomp_thread
00325 {
00326
00327 void (*fn) (void *data);
00328 void *data;
00329
00330
00331
00332 struct gomp_team_state ts;
00333
00334
00335 struct gomp_task *task;
00336
00337
00338 gomp_sem_t release;
00339
00340
00341 struct gomp_thread_pool *thread_pool;
00342 };
00343
00344
00345 struct gomp_thread_pool
00346 {
00347
00348
00349 struct gomp_thread **threads;
00350 unsigned threads_size;
00351 unsigned threads_used;
00352 struct gomp_team *last_team;
00353
00354
00355 gomp_barrier_t threads_dock;
00356 };
00357
00358
00359
00360 #ifdef HAVE_TLS
00361 extern __thread struct gomp_thread gomp_tls_data;
00362 static inline struct gomp_thread *gomp_thread (void)
00363 {
00364 return &gomp_tls_data;
00365 }
00366 #else
00367 extern pthread_key_t gomp_tls_key;
00368 static inline struct gomp_thread *gomp_thread (void)
00369 {
00370 return pthread_getspecific (gomp_tls_key);
00371 }
00372 #endif
00373
00374 extern struct gomp_task_icv *gomp_new_icv (void);
00375
00376
00377
00378 static inline struct gomp_task_icv *gomp_icv (bool write)
00379 {
00380 struct gomp_task *task = gomp_thread ()->task;
00381 if (task)
00382 return &task->icv;
00383 else if (write)
00384 return gomp_new_icv ();
00385 else
00386 return &gomp_global_icv;
00387 }
00388
00389
00390 extern pthread_attr_t gomp_thread_attr;
00391
00392
00393
00394 extern unsigned short *gomp_cpu_affinity;
00395 extern size_t gomp_cpu_affinity_len;
00396
00397
00398
00399
00400
00401 extern void gomp_init_affinity (void);
00402 extern void gomp_init_thread_affinity (pthread_attr_t *);
00403
00404
00405
00406 extern void *gomp_malloc (size_t) __attribute__((malloc));
00407 extern void *gomp_malloc_cleared (size_t) __attribute__((malloc));
00408 extern void *gomp_realloc (void *, size_t);
00409
00410
00411
00412 #define gomp_alloca(x) __builtin_alloca(x)
00413
00414
00415
00416 extern void gomp_error (const char *, ...)
00417 __attribute__((format (printf, 1, 2)));
00418 extern void gomp_fatal (const char *, ...)
00419 __attribute__((noreturn, format (printf, 1, 2)));
00420
00421
00422
00423 extern int gomp_iter_static_next (long *, long *);
00424 extern bool gomp_iter_dynamic_next_locked (long *, long *);
00425 extern bool gomp_iter_guided_next_locked (long *, long *);
00426
00427 #ifdef HAVE_SYNC_BUILTINS
00428 extern bool gomp_iter_dynamic_next (long *, long *);
00429 extern bool gomp_iter_guided_next (long *, long *);
00430 #endif
00431
00432
00433
00434 extern int gomp_iter_ull_static_next (unsigned long long *,
00435 unsigned long long *);
00436 extern bool gomp_iter_ull_dynamic_next_locked (unsigned long long *,
00437 unsigned long long *);
00438 extern bool gomp_iter_ull_guided_next_locked (unsigned long long *,
00439 unsigned long long *);
00440
00441 #if defined HAVE_SYNC_BUILTINS && defined __LP64__
00442 extern bool gomp_iter_ull_dynamic_next (unsigned long long *,
00443 unsigned long long *);
00444 extern bool gomp_iter_ull_guided_next (unsigned long long *,
00445 unsigned long long *);
00446 #endif
00447
00448
00449
00450 extern void gomp_ordered_first (void);
00451 extern void gomp_ordered_last (void);
00452 extern void gomp_ordered_next (void);
00453 extern void gomp_ordered_static_init (void);
00454 extern void gomp_ordered_static_next (void);
00455 extern void gomp_ordered_sync (void);
00456
00457
00458
00459 extern unsigned gomp_resolve_num_threads (unsigned, unsigned);
00460
00461
00462
00463 extern void gomp_init_num_threads (void);
00464 extern unsigned gomp_dynamic_max_threads (void);
00465
00466
00467
00468 extern void gomp_init_task (struct gomp_task *, struct gomp_task *,
00469 struct gomp_task_icv *);
00470 extern void gomp_end_task (void);
00471 extern void gomp_barrier_handle_tasks (gomp_barrier_state_t);
00472
00473 static void inline
00474 gomp_finish_task (struct gomp_task *task)
00475 {
00476 gomp_sem_destroy (&task->taskwait_sem);
00477 }
00478
00479
00480
00481 extern struct gomp_team *gomp_new_team (unsigned);
00482 extern void gomp_team_start (void (*) (void *), void *, unsigned,
00483 struct gomp_team *);
00484 extern void gomp_team_end (void);
00485
00486
00487
00488 extern void gomp_init_work_share (struct gomp_work_share *, bool, unsigned);
00489 extern void gomp_fini_work_share (struct gomp_work_share *);
00490 extern bool gomp_work_share_start (bool);
00491 extern void gomp_work_share_end (void);
00492 extern void gomp_work_share_end_nowait (void);
00493
00494 static inline void
00495 gomp_work_share_init_done (void)
00496 {
00497 struct gomp_thread *thr = gomp_thread ();
00498 if (__builtin_expect (thr->ts.last_work_share != NULL, 1))
00499 gomp_ptrlock_set (&thr->ts.last_work_share->next_ws, thr->ts.work_share);
00500 }
00501
00502 #ifdef HAVE_ATTRIBUTE_VISIBILITY
00503 # pragma GCC visibility pop
00504 #endif
00505
00506
00507 #include "libgomp_g.h"
00508
00509
00510 #include "omp-lock.h"
00511 #define _LIBGOMP_OMP_LOCK_DEFINED 1
00512 #include "omp.h.in"
00513
00514 #if !defined (HAVE_ATTRIBUTE_VISIBILITY) \
00515 || !defined (HAVE_ATTRIBUTE_ALIAS) \
00516 || !defined (HAVE_AS_SYMVER_DIRECTIVE) \
00517 || !defined (PIC) \
00518 || !defined (HAVE_SYMVER_SYMBOL_RENAMING_RUNTIME_SUPPORT)
00519 # undef LIBGOMP_GNU_SYMBOL_VERSIONING
00520 #endif
00521
00522 #ifdef LIBGOMP_GNU_SYMBOL_VERSIONING
00523 extern void gomp_init_lock_30 (omp_lock_t *) __GOMP_NOTHROW;
00524 extern void gomp_destroy_lock_30 (omp_lock_t *) __GOMP_NOTHROW;
00525 extern void gomp_set_lock_30 (omp_lock_t *) __GOMP_NOTHROW;
00526 extern void gomp_unset_lock_30 (omp_lock_t *) __GOMP_NOTHROW;
00527 extern int gomp_test_lock_30 (omp_lock_t *) __GOMP_NOTHROW;
00528 extern void gomp_init_nest_lock_30 (omp_nest_lock_t *) __GOMP_NOTHROW;
00529 extern void gomp_destroy_nest_lock_30 (omp_nest_lock_t *) __GOMP_NOTHROW;
00530 extern void gomp_set_nest_lock_30 (omp_nest_lock_t *) __GOMP_NOTHROW;
00531 extern void gomp_unset_nest_lock_30 (omp_nest_lock_t *) __GOMP_NOTHROW;
00532 extern int gomp_test_nest_lock_30 (omp_nest_lock_t *) __GOMP_NOTHROW;
00533
00534 extern void gomp_init_lock_25 (omp_lock_25_t *) __GOMP_NOTHROW;
00535 extern void gomp_destroy_lock_25 (omp_lock_25_t *) __GOMP_NOTHROW;
00536 extern void gomp_set_lock_25 (omp_lock_25_t *) __GOMP_NOTHROW;
00537 extern void gomp_unset_lock_25 (omp_lock_25_t *) __GOMP_NOTHROW;
00538 extern int gomp_test_lock_25 (omp_lock_25_t *) __GOMP_NOTHROW;
00539 extern void gomp_init_nest_lock_25 (omp_nest_lock_25_t *) __GOMP_NOTHROW;
00540 extern void gomp_destroy_nest_lock_25 (omp_nest_lock_25_t *) __GOMP_NOTHROW;
00541 extern void gomp_set_nest_lock_25 (omp_nest_lock_25_t *) __GOMP_NOTHROW;
00542 extern void gomp_unset_nest_lock_25 (omp_nest_lock_25_t *) __GOMP_NOTHROW;
00543 extern int gomp_test_nest_lock_25 (omp_nest_lock_25_t *) __GOMP_NOTHROW;
00544
00545 # define strong_alias(fn, al) \
00546 extern __typeof (fn) al __attribute__ ((alias (#fn)));
00547 # define omp_lock_symver(fn) \
00548 __asm (".symver g" #fn "_30, " #fn "@@OMP_3.0"); \
00549 __asm (".symver g" #fn "_25, " #fn "@OMP_1.0");
00550 #else
00551 # define gomp_init_lock_30 omp_init_lock
00552 # define gomp_destroy_lock_30 omp_destroy_lock
00553 # define gomp_set_lock_30 omp_set_lock
00554 # define gomp_unset_lock_30 omp_unset_lock
00555 # define gomp_test_lock_30 omp_test_lock
00556 # define gomp_init_nest_lock_30 omp_init_nest_lock
00557 # define gomp_destroy_nest_lock_30 omp_destroy_nest_lock
00558 # define gomp_set_nest_lock_30 omp_set_nest_lock
00559 # define gomp_unset_nest_lock_30 omp_unset_nest_lock
00560 # define gomp_test_nest_lock_30 omp_test_nest_lock
00561 #endif
00562
00563 #ifdef HAVE_ATTRIBUTE_VISIBILITY
00564 # define attribute_hidden __attribute__ ((visibility ("hidden")))
00565 #else
00566 # define attribute_hidden
00567 #endif
00568
00569 #ifdef HAVE_ATTRIBUTE_ALIAS
00570 # define ialias(fn) \
00571 extern __typeof (fn) gomp_ialias_##fn \
00572 __attribute__ ((alias (#fn))) attribute_hidden;
00573 #else
00574 # define ialias(fn)
00575 #endif
00576
00577 #endif