Intel® OpenMP* Runtime Library
 All Classes Functions Variables Typedefs Enumerations Enumerator Modules Pages
kmp_gsupport.c
1 /*
2  * kmp_gsupport.c
3  */
4 
5 /* <copyright>
6  Copyright (c) 1997-2015 Intel Corporation. All Rights Reserved.
7 
8  Redistribution and use in source and binary forms, with or without
9  modification, are permitted provided that the following conditions
10  are met:
11 
12  * Redistributions of source code must retain the above copyright
13  notice, this list of conditions and the following disclaimer.
14  * Redistributions in binary form must reproduce the above copyright
15  notice, this list of conditions and the following disclaimer in the
16  documentation and/or other materials provided with the distribution.
17  * Neither the name of Intel Corporation nor the names of its
18  contributors may be used to endorse or promote products derived
19  from this software without specific prior written permission.
20 
21  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 
33 </copyright> */
34 
35 #if defined(__x86_64) || defined (__powerpc64__) || defined(__aarch64__)
36 # define KMP_I8
37 #endif
38 #include "kmp.h"
39 #include "kmp_atomic.h"
40 
41 #ifdef __cplusplus
42  extern "C" {
43 #endif // __cplusplus
44 
45 #define MKLOC(loc,routine) \
46  static ident_t (loc) = {0, KMP_IDENT_KMPC, 0, 0, ";unknown;unknown;0;0;;" };
47 
48 #include "kmp_ftn_os.h"
49 
50 void
51 xexpand(KMP_API_NAME_GOMP_BARRIER)(void)
52 {
53  int gtid = __kmp_entry_gtid();
54  MKLOC(loc, "GOMP_barrier");
55  KA_TRACE(20, ("GOMP_barrier: T#%d\n", gtid));
56  __kmpc_barrier(&loc, gtid);
57 }
58 
59 
60 //
61 // Mutual exclusion
62 //
63 
64 //
65 // The symbol that icc/ifort generates for unnamed for unnamed critical
66 // sections - .gomp_critical_user_ - is defined using .comm in any objects
67 // reference it. We can't reference it directly here in C code, as the
68 // symbol contains a ".".
69 //
70 // The RTL contains an assembly language definition of .gomp_critical_user_
71 // with another symbol __kmp_unnamed_critical_addr initialized with it's
72 // address.
73 //
74 extern kmp_critical_name *__kmp_unnamed_critical_addr;
75 
76 
77 void
78 xexpand(KMP_API_NAME_GOMP_CRITICAL_START)(void)
79 {
80  int gtid = __kmp_entry_gtid();
81  MKLOC(loc, "GOMP_critical_start");
82  KA_TRACE(20, ("GOMP_critical_start: T#%d\n", gtid));
83  __kmpc_critical(&loc, gtid, __kmp_unnamed_critical_addr);
84 }
85 
86 
87 void
88 xexpand(KMP_API_NAME_GOMP_CRITICAL_END)(void)
89 {
90  int gtid = __kmp_get_gtid();
91  MKLOC(loc, "GOMP_critical_end");
92  KA_TRACE(20, ("GOMP_critical_end: T#%d\n", gtid));
93  __kmpc_end_critical(&loc, gtid, __kmp_unnamed_critical_addr);
94 }
95 
96 
97 void
98 xexpand(KMP_API_NAME_GOMP_CRITICAL_NAME_START)(void **pptr)
99 {
100  int gtid = __kmp_entry_gtid();
101  MKLOC(loc, "GOMP_critical_name_start");
102  KA_TRACE(20, ("GOMP_critical_name_start: T#%d\n", gtid));
103  __kmpc_critical(&loc, gtid, (kmp_critical_name *)pptr);
104 }
105 
106 
107 void
108 xexpand(KMP_API_NAME_GOMP_CRITICAL_NAME_END)(void **pptr)
109 {
110  int gtid = __kmp_get_gtid();
111  MKLOC(loc, "GOMP_critical_name_end");
112  KA_TRACE(20, ("GOMP_critical_name_end: T#%d\n", gtid));
113  __kmpc_end_critical(&loc, gtid, (kmp_critical_name *)pptr);
114 }
115 
116 
117 //
118 // The Gnu codegen tries to use locked operations to perform atomic updates
119 // inline. If it can't, then it calls GOMP_atomic_start() before performing
120 // the update and GOMP_atomic_end() afterward, regardless of the data type.
121 //
122 
123 void
124 xexpand(KMP_API_NAME_GOMP_ATOMIC_START)(void)
125 {
126  int gtid = __kmp_entry_gtid();
127  KA_TRACE(20, ("GOMP_atomic_start: T#%d\n", gtid));
128  __kmp_acquire_atomic_lock(&__kmp_atomic_lock, gtid);
129 }
130 
131 
132 void
133 xexpand(KMP_API_NAME_GOMP_ATOMIC_END)(void)
134 {
135  int gtid = __kmp_get_gtid();
136  KA_TRACE(20, ("GOMP_atomic_start: T#%d\n", gtid));
137  __kmp_release_atomic_lock(&__kmp_atomic_lock, gtid);
138 }
139 
140 
141 int
142 xexpand(KMP_API_NAME_GOMP_SINGLE_START)(void)
143 {
144  int gtid = __kmp_entry_gtid();
145  MKLOC(loc, "GOMP_single_start");
146  KA_TRACE(20, ("GOMP_single_start: T#%d\n", gtid));
147 
148  if (! TCR_4(__kmp_init_parallel))
149  __kmp_parallel_initialize();
150 
151  //
152  // 3rd parameter == FALSE prevents kmp_enter_single from pushing a
153  // workshare when USE_CHECKS is defined. We need to avoid the push,
154  // as there is no corresponding GOMP_single_end() call.
155  //
156  return __kmp_enter_single(gtid, &loc, FALSE);
157 }
158 
159 
160 void *
161 xexpand(KMP_API_NAME_GOMP_SINGLE_COPY_START)(void)
162 {
163  void *retval;
164  int gtid = __kmp_entry_gtid();
165  MKLOC(loc, "GOMP_single_copy_start");
166  KA_TRACE(20, ("GOMP_single_copy_start: T#%d\n", gtid));
167 
168  if (! TCR_4(__kmp_init_parallel))
169  __kmp_parallel_initialize();
170 
171  //
172  // If this is the first thread to enter, return NULL. The generated
173  // code will then call GOMP_single_copy_end() for this thread only,
174  // with the copyprivate data pointer as an argument.
175  //
176  if (__kmp_enter_single(gtid, &loc, FALSE))
177  return NULL;
178 
179  //
180  // Wait for the first thread to set the copyprivate data pointer,
181  // and for all other threads to reach this point.
182  //
183  __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL);
184 
185  //
186  // Retrieve the value of the copyprivate data point, and wait for all
187  // threads to do likewise, then return.
188  //
189  retval = __kmp_team_from_gtid(gtid)->t.t_copypriv_data;
190  __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL);
191  return retval;
192 }
193 
194 
195 void
196 xexpand(KMP_API_NAME_GOMP_SINGLE_COPY_END)(void *data)
197 {
198  int gtid = __kmp_get_gtid();
199  MKLOC(loc, "GOMP_single_copy_end");
200  KA_TRACE(20, ("GOMP_single_copy_end: T#%d\n", gtid));
201 
202  //
203  // Set the copyprivate data pointer fo the team, then hit the barrier
204  // so that the other threads will continue on and read it. Hit another
205  // barrier before continuing, so that the know that the copyprivate
206  // data pointer has been propagated to all threads before trying to
207  // reuse the t_copypriv_data field.
208  //
209  __kmp_team_from_gtid(gtid)->t.t_copypriv_data = data;
210  __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL);
211  __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL);
212 }
213 
214 
215 void
216 xexpand(KMP_API_NAME_GOMP_ORDERED_START)(void)
217 {
218  int gtid = __kmp_entry_gtid();
219  MKLOC(loc, "GOMP_ordered_start");
220  KA_TRACE(20, ("GOMP_ordered_start: T#%d\n", gtid));
221  __kmpc_ordered(&loc, gtid);
222 }
223 
224 
225 void
226 xexpand(KMP_API_NAME_GOMP_ORDERED_END)(void)
227 {
228  int gtid = __kmp_get_gtid();
229  MKLOC(loc, "GOMP_ordered_end");
230  KA_TRACE(20, ("GOMP_ordered_start: T#%d\n", gtid));
231  __kmpc_end_ordered(&loc, gtid);
232 }
233 
234 
235 //
236 // Dispatch macro defs
237 //
238 // They come in two flavors: 64-bit unsigned, and either 32-bit signed
239 // (IA-32 architecture) or 64-bit signed (Intel(R) 64).
240 //
241 
242 #if KMP_ARCH_X86 || KMP_ARCH_ARM
243 # define KMP_DISPATCH_INIT __kmp_aux_dispatch_init_4
244 # define KMP_DISPATCH_FINI_CHUNK __kmp_aux_dispatch_fini_chunk_4
245 # define KMP_DISPATCH_NEXT __kmpc_dispatch_next_4
246 #else
247 # define KMP_DISPATCH_INIT __kmp_aux_dispatch_init_8
248 # define KMP_DISPATCH_FINI_CHUNK __kmp_aux_dispatch_fini_chunk_8
249 # define KMP_DISPATCH_NEXT __kmpc_dispatch_next_8
250 #endif /* KMP_ARCH_X86 */
251 
252 # define KMP_DISPATCH_INIT_ULL __kmp_aux_dispatch_init_8u
253 # define KMP_DISPATCH_FINI_CHUNK_ULL __kmp_aux_dispatch_fini_chunk_8u
254 # define KMP_DISPATCH_NEXT_ULL __kmpc_dispatch_next_8u
255 
256 
257 //
258 // The parallel contruct
259 //
260 
261 #ifndef KMP_DEBUG
262 static
263 #endif /* KMP_DEBUG */
264 void
265 __kmp_GOMP_microtask_wrapper(int *gtid, int *npr, void (*task)(void *),
266  void *data)
267 {
268  task(data);
269 }
270 
271 
272 #ifndef KMP_DEBUG
273 static
274 #endif /* KMP_DEBUG */
275 void
276 __kmp_GOMP_parallel_microtask_wrapper(int *gtid, int *npr,
277  void (*task)(void *), void *data, unsigned num_threads, ident_t *loc,
278  enum sched_type schedule, long start, long end, long incr, long chunk_size)
279 {
280  //
281  // Intialize the loop worksharing construct.
282  //
283  KMP_DISPATCH_INIT(loc, *gtid, schedule, start, end, incr, chunk_size,
284  schedule != kmp_sch_static);
285 
286  //
287  // Now invoke the microtask.
288  //
289  task(data);
290 }
291 
292 
293 #ifndef KMP_DEBUG
294 static
295 #endif /* KMP_DEBUG */
296 void
297 __kmp_GOMP_fork_call(ident_t *loc, int gtid, microtask_t wrapper, int argc,...)
298 {
299  int rc;
300 
301  va_list ap;
302  va_start(ap, argc);
303 
304  rc = __kmp_fork_call(loc, gtid, fork_context_gnu, argc, wrapper, __kmp_invoke_task_func,
305 #if (KMP_ARCH_X86_64 || KMP_ARCH_ARM || KMP_ARCH_AARCH64) && KMP_OS_LINUX
306  &ap
307 #else
308  ap
309 #endif
310  );
311 
312  va_end(ap);
313 
314  if (rc) {
315  kmp_info_t *thr = __kmp_threads[gtid];
316  __kmp_run_before_invoked_task(gtid, __kmp_tid_from_gtid(gtid), thr,
317  thr->th.th_team);
318  }
319 }
320 
321 
322 void
323 xexpand(KMP_API_NAME_GOMP_PARALLEL_START)(void (*task)(void *), void *data, unsigned num_threads)
324 {
325  int gtid = __kmp_entry_gtid();
326  MKLOC(loc, "GOMP_parallel_start");
327  KA_TRACE(20, ("GOMP_parallel_start: T#%d\n", gtid));
328 
329  if (__kmpc_ok_to_fork(&loc) && (num_threads != 1)) {
330  if (num_threads != 0) {
331  __kmp_push_num_threads(&loc, gtid, num_threads);
332  }
333  __kmp_GOMP_fork_call(&loc, gtid,
334  (microtask_t)__kmp_GOMP_microtask_wrapper, 2, task, data);
335  }
336  else {
337  __kmpc_serialized_parallel(&loc, gtid);
338  }
339 }
340 
341 
342 void
343 xexpand(KMP_API_NAME_GOMP_PARALLEL_END)(void)
344 {
345  int gtid = __kmp_get_gtid();
346  MKLOC(loc, "GOMP_parallel_end");
347  KA_TRACE(20, ("GOMP_parallel_end: T#%d\n", gtid));
348 
349  if (! __kmp_threads[gtid]->th.th_team->t.t_serialized) {
350  kmp_info_t *thr = __kmp_threads[gtid];
351  __kmp_run_after_invoked_task(gtid, __kmp_tid_from_gtid(gtid), thr,
352  thr->th.th_team);
353  __kmp_join_call(&loc, gtid);
354  }
355  else {
356  __kmpc_end_serialized_parallel(&loc, gtid);
357  }
358 }
359 
360 
361 //
362 // Loop worksharing constructs
363 //
364 
365 //
366 // The Gnu codegen passes in an exclusive upper bound for the overall range,
367 // but the libguide dispatch code expects an inclusive upper bound, hence the
368 // "end - incr" 5th argument to KMP_DISPATCH_INIT (and the " ub - str" 11th
369 // argument to __kmp_GOMP_fork_call).
370 //
371 // Conversely, KMP_DISPATCH_NEXT returns and inclusive upper bound in *p_ub,
372 // but the Gnu codegen expects an excluside upper bound, so the adjustment
373 // "*p_ub += stride" compenstates for the discrepancy.
374 //
375 // Correction: the gnu codegen always adjusts the upper bound by +-1, not the
376 // stride value. We adjust the dispatch parameters accordingly (by +-1), but
377 // we still adjust p_ub by the actual stride value.
378 //
379 // The "runtime" versions do not take a chunk_sz parameter.
380 //
381 // The profile lib cannot support construct checking of unordered loops that
382 // are predetermined by the compiler to be statically scheduled, as the gcc
383 // codegen will not always emit calls to GOMP_loop_static_next() to get the
384 // next iteration. Instead, it emits inline code to call omp_get_thread_num()
385 // num and calculate the iteration space using the result. It doesn't do this
386 // with ordered static loop, so they can be checked.
387 //
388 
389 #define LOOP_START(func,schedule) \
390  int func (long lb, long ub, long str, long chunk_sz, long *p_lb, \
391  long *p_ub) \
392  { \
393  int status; \
394  long stride; \
395  int gtid = __kmp_entry_gtid(); \
396  MKLOC(loc, #func); \
397  KA_TRACE(20, ( #func ": T#%d, lb 0x%lx, ub 0x%lx, str 0x%lx, chunk_sz 0x%lx\n", \
398  gtid, lb, ub, str, chunk_sz )); \
399  \
400  if ((str > 0) ? (lb < ub) : (lb > ub)) { \
401  KMP_DISPATCH_INIT(&loc, gtid, (schedule), lb, \
402  (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz, \
403  (schedule) != kmp_sch_static); \
404  status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, (kmp_int *)p_lb, \
405  (kmp_int *)p_ub, (kmp_int *)&stride); \
406  if (status) { \
407  KMP_DEBUG_ASSERT(stride == str); \
408  *p_ub += (str > 0) ? 1 : -1; \
409  } \
410  } \
411  else { \
412  status = 0; \
413  } \
414  \
415  KA_TRACE(20, ( #func " exit: T#%d, *p_lb 0x%lx, *p_ub 0x%lx, returning %d\n", \
416  gtid, *p_lb, *p_ub, status)); \
417  return status; \
418  }
419 
420 
421 #define LOOP_RUNTIME_START(func,schedule) \
422  int func (long lb, long ub, long str, long *p_lb, long *p_ub) \
423  { \
424  int status; \
425  long stride; \
426  long chunk_sz = 0; \
427  int gtid = __kmp_entry_gtid(); \
428  MKLOC(loc, #func); \
429  KA_TRACE(20, ( #func ": T#%d, lb 0x%lx, ub 0x%lx, str 0x%lx, chunk_sz %d\n", \
430  gtid, lb, ub, str, chunk_sz )); \
431  \
432  if ((str > 0) ? (lb < ub) : (lb > ub)) { \
433  KMP_DISPATCH_INIT(&loc, gtid, (schedule), lb, \
434  (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz, TRUE); \
435  status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, (kmp_int *)p_lb, \
436  (kmp_int *)p_ub, (kmp_int *)&stride); \
437  if (status) { \
438  KMP_DEBUG_ASSERT(stride == str); \
439  *p_ub += (str > 0) ? 1 : -1; \
440  } \
441  } \
442  else { \
443  status = 0; \
444  } \
445  \
446  KA_TRACE(20, ( #func " exit: T#%d, *p_lb 0x%lx, *p_ub 0x%lx, returning %d\n", \
447  gtid, *p_lb, *p_ub, status)); \
448  return status; \
449  }
450 
451 
452 #define LOOP_NEXT(func,fini_code) \
453  int func(long *p_lb, long *p_ub) \
454  { \
455  int status; \
456  long stride; \
457  int gtid = __kmp_get_gtid(); \
458  MKLOC(loc, #func); \
459  KA_TRACE(20, ( #func ": T#%d\n", gtid)); \
460  \
461  fini_code \
462  status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, (kmp_int *)p_lb, \
463  (kmp_int *)p_ub, (kmp_int *)&stride); \
464  if (status) { \
465  *p_ub += (stride > 0) ? 1 : -1; \
466  } \
467  \
468  KA_TRACE(20, ( #func " exit: T#%d, *p_lb 0x%lx, *p_ub 0x%lx, stride 0x%lx, " \
469  "returning %d\n", gtid, *p_lb, *p_ub, stride, status)); \
470  return status; \
471  }
472 
473 
474 LOOP_START(xexpand(KMP_API_NAME_GOMP_LOOP_STATIC_START), kmp_sch_static)
475 LOOP_NEXT(xexpand(KMP_API_NAME_GOMP_LOOP_STATIC_NEXT), {})
476 LOOP_START(xexpand(KMP_API_NAME_GOMP_LOOP_DYNAMIC_START), kmp_sch_dynamic_chunked)
477 LOOP_NEXT(xexpand(KMP_API_NAME_GOMP_LOOP_DYNAMIC_NEXT), {})
478 LOOP_START(xexpand(KMP_API_NAME_GOMP_LOOP_GUIDED_START), kmp_sch_guided_chunked)
479 LOOP_NEXT(xexpand(KMP_API_NAME_GOMP_LOOP_GUIDED_NEXT), {})
480 LOOP_RUNTIME_START(xexpand(KMP_API_NAME_GOMP_LOOP_RUNTIME_START), kmp_sch_runtime)
481 LOOP_NEXT(xexpand(KMP_API_NAME_GOMP_LOOP_RUNTIME_NEXT), {})
482 
483 LOOP_START(xexpand(KMP_API_NAME_GOMP_LOOP_ORDERED_STATIC_START), kmp_ord_static)
484 LOOP_NEXT(xexpand(KMP_API_NAME_GOMP_LOOP_ORDERED_STATIC_NEXT), \
485  { KMP_DISPATCH_FINI_CHUNK(&loc, gtid); })
486 LOOP_START(xexpand(KMP_API_NAME_GOMP_LOOP_ORDERED_DYNAMIC_START), kmp_ord_dynamic_chunked)
487 LOOP_NEXT(xexpand(KMP_API_NAME_GOMP_LOOP_ORDERED_DYNAMIC_NEXT), \
488  { KMP_DISPATCH_FINI_CHUNK(&loc, gtid); })
489 LOOP_START(xexpand(KMP_API_NAME_GOMP_LOOP_ORDERED_GUIDED_START), kmp_ord_guided_chunked)
490 LOOP_NEXT(xexpand(KMP_API_NAME_GOMP_LOOP_ORDERED_GUIDED_NEXT), \
491  { KMP_DISPATCH_FINI_CHUNK(&loc, gtid); })
492 LOOP_RUNTIME_START(xexpand(KMP_API_NAME_GOMP_LOOP_ORDERED_RUNTIME_START), kmp_ord_runtime)
493 LOOP_NEXT(xexpand(KMP_API_NAME_GOMP_LOOP_ORDERED_RUNTIME_NEXT), \
494  { KMP_DISPATCH_FINI_CHUNK(&loc, gtid); })
495 
496 
497 void
498 xexpand(KMP_API_NAME_GOMP_LOOP_END)(void)
499 {
500  int gtid = __kmp_get_gtid();
501  KA_TRACE(20, ("GOMP_loop_end: T#%d\n", gtid))
502 
503  __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL);
504 
505  KA_TRACE(20, ("GOMP_loop_end exit: T#%d\n", gtid))
506 }
507 
508 
509 void
510 xexpand(KMP_API_NAME_GOMP_LOOP_END_NOWAIT)(void)
511 {
512  KA_TRACE(20, ("GOMP_loop_end_nowait: T#%d\n", __kmp_get_gtid()))
513 }
514 
515 
516 //
517 // Unsigned long long loop worksharing constructs
518 //
519 // These are new with gcc 4.4
520 //
521 
522 #define LOOP_START_ULL(func,schedule) \
523  int func (int up, unsigned long long lb, unsigned long long ub, \
524  unsigned long long str, unsigned long long chunk_sz, \
525  unsigned long long *p_lb, unsigned long long *p_ub) \
526  { \
527  int status; \
528  long long str2 = up ? ((long long)str) : -((long long)str); \
529  long long stride; \
530  int gtid = __kmp_entry_gtid(); \
531  MKLOC(loc, #func); \
532  \
533  KA_TRACE(20, ( #func ": T#%d, up %d, lb 0x%llx, ub 0x%llx, str 0x%llx, chunk_sz 0x%llx\n", \
534  gtid, up, lb, ub, str, chunk_sz )); \
535  \
536  if ((str > 0) ? (lb < ub) : (lb > ub)) { \
537  KMP_DISPATCH_INIT_ULL(&loc, gtid, (schedule), lb, \
538  (str2 > 0) ? (ub - 1) : (ub + 1), str2, chunk_sz, \
539  (schedule) != kmp_sch_static); \
540  status = KMP_DISPATCH_NEXT_ULL(&loc, gtid, NULL, \
541  (kmp_uint64 *)p_lb, (kmp_uint64 *)p_ub, (kmp_int64 *)&stride); \
542  if (status) { \
543  KMP_DEBUG_ASSERT(stride == str2); \
544  *p_ub += (str > 0) ? 1 : -1; \
545  } \
546  } \
547  else { \
548  status = 0; \
549  } \
550  \
551  KA_TRACE(20, ( #func " exit: T#%d, *p_lb 0x%llx, *p_ub 0x%llx, returning %d\n", \
552  gtid, *p_lb, *p_ub, status)); \
553  return status; \
554  }
555 
556 
557 #define LOOP_RUNTIME_START_ULL(func,schedule) \
558  int func (int up, unsigned long long lb, unsigned long long ub, \
559  unsigned long long str, unsigned long long *p_lb, \
560  unsigned long long *p_ub) \
561  { \
562  int status; \
563  long long str2 = up ? ((long long)str) : -((long long)str); \
564  unsigned long long stride; \
565  unsigned long long chunk_sz = 0; \
566  int gtid = __kmp_entry_gtid(); \
567  MKLOC(loc, #func); \
568  \
569  KA_TRACE(20, ( #func ": T#%d, up %d, lb 0x%llx, ub 0x%llx, str 0x%llx, chunk_sz 0x%llx\n", \
570  gtid, up, lb, ub, str, chunk_sz )); \
571  \
572  if ((str > 0) ? (lb < ub) : (lb > ub)) { \
573  KMP_DISPATCH_INIT_ULL(&loc, gtid, (schedule), lb, \
574  (str2 > 0) ? (ub - 1) : (ub + 1), str2, chunk_sz, TRUE); \
575  status = KMP_DISPATCH_NEXT_ULL(&loc, gtid, NULL, \
576  (kmp_uint64 *)p_lb, (kmp_uint64 *)p_ub, (kmp_int64 *)&stride); \
577  if (status) { \
578  KMP_DEBUG_ASSERT((long long)stride == str2); \
579  *p_ub += (str > 0) ? 1 : -1; \
580  } \
581  } \
582  else { \
583  status = 0; \
584  } \
585  \
586  KA_TRACE(20, ( #func " exit: T#%d, *p_lb 0x%llx, *p_ub 0x%llx, returning %d\n", \
587  gtid, *p_lb, *p_ub, status)); \
588  return status; \
589  }
590 
591 
592 #define LOOP_NEXT_ULL(func,fini_code) \
593  int func(unsigned long long *p_lb, unsigned long long *p_ub) \
594  { \
595  int status; \
596  long long stride; \
597  int gtid = __kmp_get_gtid(); \
598  MKLOC(loc, #func); \
599  KA_TRACE(20, ( #func ": T#%d\n", gtid)); \
600  \
601  fini_code \
602  status = KMP_DISPATCH_NEXT_ULL(&loc, gtid, NULL, (kmp_uint64 *)p_lb, \
603  (kmp_uint64 *)p_ub, (kmp_int64 *)&stride); \
604  if (status) { \
605  *p_ub += (stride > 0) ? 1 : -1; \
606  } \
607  \
608  KA_TRACE(20, ( #func " exit: T#%d, *p_lb 0x%llx, *p_ub 0x%llx, stride 0x%llx, " \
609  "returning %d\n", gtid, *p_lb, *p_ub, stride, status)); \
610  return status; \
611  }
612 
613 
614 LOOP_START_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_STATIC_START), kmp_sch_static)
615 LOOP_NEXT_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_STATIC_NEXT), {})
616 LOOP_START_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_DYNAMIC_START), kmp_sch_dynamic_chunked)
617 LOOP_NEXT_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_DYNAMIC_NEXT), {})
618 LOOP_START_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_GUIDED_START), kmp_sch_guided_chunked)
619 LOOP_NEXT_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_GUIDED_NEXT), {})
620 LOOP_RUNTIME_START_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_RUNTIME_START), kmp_sch_runtime)
621 LOOP_NEXT_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_RUNTIME_NEXT), {})
622 
623 LOOP_START_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_STATIC_START), kmp_ord_static)
624 LOOP_NEXT_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_STATIC_NEXT), \
625  { KMP_DISPATCH_FINI_CHUNK_ULL(&loc, gtid); })
626 LOOP_START_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_DYNAMIC_START), kmp_ord_dynamic_chunked)
627 LOOP_NEXT_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_DYNAMIC_NEXT), \
628  { KMP_DISPATCH_FINI_CHUNK_ULL(&loc, gtid); })
629 LOOP_START_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_GUIDED_START), kmp_ord_guided_chunked)
630 LOOP_NEXT_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_GUIDED_NEXT), \
631  { KMP_DISPATCH_FINI_CHUNK_ULL(&loc, gtid); })
632 LOOP_RUNTIME_START_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_START), kmp_ord_runtime)
633 LOOP_NEXT_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_NEXT), \
634  { KMP_DISPATCH_FINI_CHUNK_ULL(&loc, gtid); })
635 
636 
637 //
638 // Combined parallel / loop worksharing constructs
639 //
640 // There are no ull versions (yet).
641 //
642 
643 #define PARALLEL_LOOP_START(func, schedule) \
644  void func (void (*task) (void *), void *data, unsigned num_threads, \
645  long lb, long ub, long str, long chunk_sz) \
646  { \
647  int gtid = __kmp_entry_gtid(); \
648  int last = FALSE; \
649  MKLOC(loc, #func); \
650  KA_TRACE(20, ( #func ": T#%d, lb 0x%lx, ub 0x%lx, str 0x%lx, chunk_sz 0x%lx\n", \
651  gtid, lb, ub, str, chunk_sz )); \
652  \
653  if (__kmpc_ok_to_fork(&loc) && (num_threads != 1)) { \
654  if (num_threads != 0) { \
655  __kmp_push_num_threads(&loc, gtid, num_threads); \
656  } \
657  __kmp_GOMP_fork_call(&loc, gtid, \
658  (microtask_t)__kmp_GOMP_parallel_microtask_wrapper, 9, \
659  task, data, num_threads, &loc, (schedule), lb, \
660  (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz); \
661  } \
662  else { \
663  __kmpc_serialized_parallel(&loc, gtid); \
664  } \
665  \
666  KMP_DISPATCH_INIT(&loc, gtid, (schedule), lb, \
667  (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz, \
668  (schedule) != kmp_sch_static); \
669  \
670  KA_TRACE(20, ( #func " exit: T#%d\n", gtid)); \
671  }
672 
673 
674 PARALLEL_LOOP_START(xexpand(KMP_API_NAME_GOMP_PARALLEL_LOOP_STATIC_START), kmp_sch_static)
675 PARALLEL_LOOP_START(xexpand(KMP_API_NAME_GOMP_PARALLEL_LOOP_DYNAMIC_START), kmp_sch_dynamic_chunked)
676 PARALLEL_LOOP_START(xexpand(KMP_API_NAME_GOMP_PARALLEL_LOOP_GUIDED_START), kmp_sch_guided_chunked)
677 PARALLEL_LOOP_START(xexpand(KMP_API_NAME_GOMP_PARALLEL_LOOP_RUNTIME_START), kmp_sch_runtime)
678 
679 
680 //
681 // Tasking constructs
682 //
683 
684 void
685 xexpand(KMP_API_NAME_GOMP_TASK)(void (*func)(void *), void *data, void (*copy_func)(void *, void *),
686  long arg_size, long arg_align, int if_cond, unsigned gomp_flags)
687 {
688  MKLOC(loc, "GOMP_task");
689  int gtid = __kmp_entry_gtid();
690  kmp_int32 flags = 0;
691  kmp_tasking_flags_t *input_flags = (kmp_tasking_flags_t *) & flags;
692 
693  KA_TRACE(20, ("GOMP_task: T#%d\n", gtid));
694 
695  // The low-order bit is the "tied" flag
696  if (gomp_flags & 1) {
697  input_flags->tiedness = 1;
698  }
699  input_flags->native = 1;
700  // __kmp_task_alloc() sets up all other flags
701 
702  if (! if_cond) {
703  arg_size = 0;
704  }
705 
706  kmp_task_t *task = __kmp_task_alloc(&loc, gtid, input_flags,
707  sizeof(kmp_task_t), arg_size ? arg_size + arg_align - 1 : 0,
708  (kmp_routine_entry_t)func);
709 
710  if (arg_size > 0) {
711  if (arg_align > 0) {
712  task->shareds = (void *)((((size_t)task->shareds)
713  + arg_align - 1) / arg_align * arg_align);
714  }
715  //else error??
716 
717  if (copy_func) {
718  (*copy_func)(task->shareds, data);
719  }
720  else {
721  KMP_MEMCPY(task->shareds, data, arg_size);
722  }
723  }
724 
725  if (if_cond) {
726  __kmpc_omp_task(&loc, gtid, task);
727  }
728  else {
729  __kmpc_omp_task_begin_if0(&loc, gtid, task);
730  func(data);
731  __kmpc_omp_task_complete_if0(&loc, gtid, task);
732  }
733 
734  KA_TRACE(20, ("GOMP_task exit: T#%d\n", gtid));
735 }
736 
737 
738 void
739 xexpand(KMP_API_NAME_GOMP_TASKWAIT)(void)
740 {
741  MKLOC(loc, "GOMP_taskwait");
742  int gtid = __kmp_entry_gtid();
743 
744  KA_TRACE(20, ("GOMP_taskwait: T#%d\n", gtid));
745 
746  __kmpc_omp_taskwait(&loc, gtid);
747 
748  KA_TRACE(20, ("GOMP_taskwait exit: T#%d\n", gtid));
749 }
750 
751 
752 //
753 // Sections worksharing constructs
754 //
755 
756 //
757 // For the sections construct, we initialize a dynamically scheduled loop
758 // worksharing construct with lb 1 and stride 1, and use the iteration #'s
759 // that its returns as sections ids.
760 //
761 // There are no special entry points for ordered sections, so we always use
762 // the dynamically scheduled workshare, even if the sections aren't ordered.
763 //
764 
765 unsigned
766 xexpand(KMP_API_NAME_GOMP_SECTIONS_START)(unsigned count)
767 {
768  int status;
769  kmp_int lb, ub, stride;
770  int gtid = __kmp_entry_gtid();
771  MKLOC(loc, "GOMP_sections_start");
772  KA_TRACE(20, ("GOMP_sections_start: T#%d\n", gtid));
773 
774  KMP_DISPATCH_INIT(&loc, gtid, kmp_nm_dynamic_chunked, 1, count, 1, 1, TRUE);
775 
776  status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, &lb, &ub, &stride);
777  if (status) {
778  KMP_DEBUG_ASSERT(stride == 1);
779  KMP_DEBUG_ASSERT(lb > 0);
780  KMP_ASSERT(lb == ub);
781  }
782  else {
783  lb = 0;
784  }
785 
786  KA_TRACE(20, ("GOMP_sections_start exit: T#%d returning %u\n", gtid,
787  (unsigned)lb));
788  return (unsigned)lb;
789 }
790 
791 
792 unsigned
793 xexpand(KMP_API_NAME_GOMP_SECTIONS_NEXT)(void)
794 {
795  int status;
796  kmp_int lb, ub, stride;
797  int gtid = __kmp_get_gtid();
798  MKLOC(loc, "GOMP_sections_next");
799  KA_TRACE(20, ("GOMP_sections_next: T#%d\n", gtid));
800 
801  status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, &lb, &ub, &stride);
802  if (status) {
803  KMP_DEBUG_ASSERT(stride == 1);
804  KMP_DEBUG_ASSERT(lb > 0);
805  KMP_ASSERT(lb == ub);
806  }
807  else {
808  lb = 0;
809  }
810 
811  KA_TRACE(20, ("GOMP_sections_next exit: T#%d returning %u\n", gtid,
812  (unsigned)lb));
813  return (unsigned)lb;
814 }
815 
816 
817 void
818 xexpand(KMP_API_NAME_GOMP_PARALLEL_SECTIONS_START)(void (*task) (void *), void *data,
819  unsigned num_threads, unsigned count)
820 {
821  int gtid = __kmp_entry_gtid();
822  int last = FALSE;
823  MKLOC(loc, "GOMP_parallel_sections_start");
824  KA_TRACE(20, ("GOMP_parallel_sections_start: T#%d\n", gtid));
825 
826  if (__kmpc_ok_to_fork(&loc) && (num_threads != 1)) {
827  if (num_threads != 0) {
828  __kmp_push_num_threads(&loc, gtid, num_threads);
829  }
830  __kmp_GOMP_fork_call(&loc, gtid,
831  (microtask_t)__kmp_GOMP_parallel_microtask_wrapper, 9, task, data,
832  num_threads, &loc, kmp_nm_dynamic_chunked, (kmp_int)1,
833  (kmp_int)count, (kmp_int)1, (kmp_int)1);
834  }
835  else {
836  __kmpc_serialized_parallel(&loc, gtid);
837  }
838 
839  KMP_DISPATCH_INIT(&loc, gtid, kmp_nm_dynamic_chunked, 1, count, 1, 1, TRUE);
840 
841  KA_TRACE(20, ("GOMP_parallel_sections_start exit: T#%d\n", gtid));
842 }
843 
844 
845 void
846 xexpand(KMP_API_NAME_GOMP_SECTIONS_END)(void)
847 {
848  int gtid = __kmp_get_gtid();
849  KA_TRACE(20, ("GOMP_sections_end: T#%d\n", gtid))
850 
851  __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL);
852 
853  KA_TRACE(20, ("GOMP_sections_end exit: T#%d\n", gtid))
854 }
855 
856 
857 void
858 xexpand(KMP_API_NAME_GOMP_SECTIONS_END_NOWAIT)(void)
859 {
860  KA_TRACE(20, ("GOMP_sections_end_nowait: T#%d\n", __kmp_get_gtid()))
861 }
862 
863 // libgomp has an empty function for GOMP_taskyield as of 2013-10-10
864 void
865 xexpand(KMP_API_NAME_GOMP_TASKYIELD)(void)
866 {
867  KA_TRACE(20, ("GOMP_taskyield: T#%d\n", __kmp_get_gtid()))
868  return;
869 }
870 
871 #if OMP_40_ENABLED // these are new GOMP_4.0 entry points
872 
873 void
874 xexpand(KMP_API_NAME_GOMP_PARALLEL)(void (*task)(void *), void *data, unsigned num_threads, unsigned int flags)
875 {
876  int gtid = __kmp_entry_gtid();
877  MKLOC(loc, "GOMP_parallel");
878  KA_TRACE(20, ("GOMP_parallel: T#%d\n", gtid));
879 
880  if (__kmpc_ok_to_fork(&loc) && (num_threads != 1)) {
881  if (num_threads != 0) {
882  __kmp_push_num_threads(&loc, gtid, num_threads);
883  }
884  if(flags != 0) {
885  __kmp_push_proc_bind(&loc, gtid, (kmp_proc_bind_t)flags);
886  }
887  __kmp_GOMP_fork_call(&loc, gtid,
888  (microtask_t)__kmp_GOMP_microtask_wrapper, 2, task, data);
889  }
890  else {
891  __kmpc_serialized_parallel(&loc, gtid);
892  }
893  task(data);
894  xexpand(KMP_API_NAME_GOMP_PARALLEL_END)();
895 }
896 
897 void
898 xexpand(KMP_API_NAME_GOMP_PARALLEL_SECTIONS)(void (*task) (void *), void *data,
899  unsigned num_threads, unsigned count, unsigned flags)
900 {
901  int gtid = __kmp_entry_gtid();
902  int last = FALSE;
903  MKLOC(loc, "GOMP_parallel_sections");
904  KA_TRACE(20, ("GOMP_parallel_sections: T#%d\n", gtid));
905 
906  if (__kmpc_ok_to_fork(&loc) && (num_threads != 1)) {
907  if (num_threads != 0) {
908  __kmp_push_num_threads(&loc, gtid, num_threads);
909  }
910  if(flags != 0) {
911  __kmp_push_proc_bind(&loc, gtid, (kmp_proc_bind_t)flags);
912  }
913  __kmp_GOMP_fork_call(&loc, gtid,
914  (microtask_t)__kmp_GOMP_parallel_microtask_wrapper, 9, task, data,
915  num_threads, &loc, kmp_nm_dynamic_chunked, (kmp_int)1,
916  (kmp_int)count, (kmp_int)1, (kmp_int)1);
917  }
918  else {
919  __kmpc_serialized_parallel(&loc, gtid);
920  }
921 
922  KMP_DISPATCH_INIT(&loc, gtid, kmp_nm_dynamic_chunked, 1, count, 1, 1, TRUE);
923 
924  task(data);
925  xexpand(KMP_API_NAME_GOMP_PARALLEL_END)();
926  KA_TRACE(20, ("GOMP_parallel_sections exit: T#%d\n", gtid));
927 }
928 
929 #define PARALLEL_LOOP(func, schedule) \
930  void func (void (*task) (void *), void *data, unsigned num_threads, \
931  long lb, long ub, long str, long chunk_sz, unsigned flags) \
932  { \
933  int gtid = __kmp_entry_gtid(); \
934  int last = FALSE; \
935  MKLOC(loc, #func); \
936  KA_TRACE(20, ( #func ": T#%d, lb 0x%lx, ub 0x%lx, str 0x%lx, chunk_sz 0x%lx\n", \
937  gtid, lb, ub, str, chunk_sz )); \
938  \
939  if (__kmpc_ok_to_fork(&loc) && (num_threads != 1)) { \
940  if (num_threads != 0) { \
941  __kmp_push_num_threads(&loc, gtid, num_threads); \
942  } \
943  if (flags != 0) { \
944  __kmp_push_proc_bind(&loc, gtid, (kmp_proc_bind_t)flags); \
945  } \
946  __kmp_GOMP_fork_call(&loc, gtid, \
947  (microtask_t)__kmp_GOMP_parallel_microtask_wrapper, 9, \
948  task, data, num_threads, &loc, (schedule), lb, \
949  (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz); \
950  } \
951  else { \
952  __kmpc_serialized_parallel(&loc, gtid); \
953  } \
954  \
955  KMP_DISPATCH_INIT(&loc, gtid, (schedule), lb, \
956  (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz, \
957  (schedule) != kmp_sch_static); \
958  task(data); \
959  xexpand(KMP_API_NAME_GOMP_PARALLEL_END)(); \
960  \
961  KA_TRACE(20, ( #func " exit: T#%d\n", gtid)); \
962  }
963 
964 PARALLEL_LOOP(xexpand(KMP_API_NAME_GOMP_PARALLEL_LOOP_STATIC), kmp_sch_static)
965 PARALLEL_LOOP(xexpand(KMP_API_NAME_GOMP_PARALLEL_LOOP_DYNAMIC), kmp_sch_dynamic_chunked)
966 PARALLEL_LOOP(xexpand(KMP_API_NAME_GOMP_PARALLEL_LOOP_GUIDED), kmp_sch_guided_chunked)
967 PARALLEL_LOOP(xexpand(KMP_API_NAME_GOMP_PARALLEL_LOOP_RUNTIME), kmp_sch_runtime)
968 
969 
970 void
971 xexpand(KMP_API_NAME_GOMP_TASKGROUP_START)(void)
972 {
973  int gtid = __kmp_get_gtid();
974  MKLOC(loc, "GOMP_taskgroup_start");
975  KA_TRACE(20, ("GOMP_taskgroup_start: T#%d\n", gtid));
976 
977  __kmpc_taskgroup(&loc, gtid);
978 
979  return;
980 }
981 
982 void
983 xexpand(KMP_API_NAME_GOMP_TASKGROUP_END)(void)
984 {
985  int gtid = __kmp_get_gtid();
986  MKLOC(loc, "GOMP_taskgroup_end");
987  KA_TRACE(20, ("GOMP_taskgroup_end: T#%d\n", gtid));
988 
989  __kmpc_end_taskgroup(&loc, gtid);
990 
991  return;
992 }
993 
994 #ifndef KMP_DEBUG
995 static
996 #endif /* KMP_DEBUG */
997 kmp_int32 __kmp_gomp_to_iomp_cancellation_kind(int gomp_kind) {
998  kmp_int32 cncl_kind = 0;
999  switch(gomp_kind) {
1000  case 1:
1001  cncl_kind = cancel_parallel;
1002  break;
1003  case 2:
1004  cncl_kind = cancel_loop;
1005  break;
1006  case 4:
1007  cncl_kind = cancel_sections;
1008  break;
1009  case 8:
1010  cncl_kind = cancel_taskgroup;
1011  break;
1012  }
1013  return cncl_kind;
1014 }
1015 
1016 bool
1017 xexpand(KMP_API_NAME_GOMP_CANCELLATION_POINT)(int which)
1018 {
1019  if(__kmp_omp_cancellation) {
1020  KMP_FATAL(NoGompCancellation);
1021  }
1022  int gtid = __kmp_get_gtid();
1023  MKLOC(loc, "GOMP_cancellation_point");
1024  KA_TRACE(20, ("GOMP_cancellation_point: T#%d\n", gtid));
1025 
1026  kmp_int32 cncl_kind = __kmp_gomp_to_iomp_cancellation_kind(which);
1027 
1028  return __kmpc_cancellationpoint(&loc, gtid, cncl_kind);
1029 }
1030 
1031 bool
1032 xexpand(KMP_API_NAME_GOMP_BARRIER_CANCEL)(void)
1033 {
1034  if(__kmp_omp_cancellation) {
1035  KMP_FATAL(NoGompCancellation);
1036  }
1037  KMP_FATAL(NoGompCancellation);
1038  int gtid = __kmp_get_gtid();
1039  MKLOC(loc, "GOMP_barrier_cancel");
1040  KA_TRACE(20, ("GOMP_barrier_cancel: T#%d\n", gtid));
1041 
1042  return __kmpc_cancel_barrier(&loc, gtid);
1043 }
1044 
1045 bool
1046 xexpand(KMP_API_NAME_GOMP_CANCEL)(int which, bool do_cancel)
1047 {
1048  if(__kmp_omp_cancellation) {
1049  KMP_FATAL(NoGompCancellation);
1050  } else {
1051  return FALSE;
1052  }
1053 
1054  int gtid = __kmp_get_gtid();
1055  MKLOC(loc, "GOMP_cancel");
1056  KA_TRACE(20, ("GOMP_cancel: T#%d\n", gtid));
1057 
1058  kmp_int32 cncl_kind = __kmp_gomp_to_iomp_cancellation_kind(which);
1059 
1060  if(do_cancel == FALSE) {
1061  return xexpand(KMP_API_NAME_GOMP_CANCELLATION_POINT)(which);
1062  } else {
1063  return __kmpc_cancel(&loc, gtid, cncl_kind);
1064  }
1065 }
1066 
1067 bool
1068 xexpand(KMP_API_NAME_GOMP_SECTIONS_END_CANCEL)(void)
1069 {
1070  if(__kmp_omp_cancellation) {
1071  KMP_FATAL(NoGompCancellation);
1072  }
1073  int gtid = __kmp_get_gtid();
1074  MKLOC(loc, "GOMP_sections_end_cancel");
1075  KA_TRACE(20, ("GOMP_sections_end_cancel: T#%d\n", gtid));
1076 
1077  return __kmpc_cancel_barrier(&loc, gtid);
1078 }
1079 
1080 bool
1081 xexpand(KMP_API_NAME_GOMP_LOOP_END_CANCEL)(void)
1082 {
1083  if(__kmp_omp_cancellation) {
1084  KMP_FATAL(NoGompCancellation);
1085  }
1086  int gtid = __kmp_get_gtid();
1087  MKLOC(loc, "GOMP_loop_end_cancel");
1088  KA_TRACE(20, ("GOMP_loop_end_cancel: T#%d\n", gtid));
1089 
1090  return __kmpc_cancel_barrier(&loc, gtid);
1091 }
1092 
1093 // All target functions are empty as of 2014-05-29
1094 void
1095 xexpand(KMP_API_NAME_GOMP_TARGET)(int device, void (*fn) (void *), const void *openmp_target,
1096  size_t mapnum, void **hostaddrs, size_t *sizes, unsigned char *kinds)
1097 {
1098  return;
1099 }
1100 
1101 void
1102 xexpand(KMP_API_NAME_GOMP_TARGET_DATA)(int device, const void *openmp_target, size_t mapnum,
1103  void **hostaddrs, size_t *sizes, unsigned char *kinds)
1104 {
1105  return;
1106 }
1107 
1108 void
1109 xexpand(KMP_API_NAME_GOMP_TARGET_END_DATA)(void)
1110 {
1111  return;
1112 }
1113 
1114 void
1115 xexpand(KMP_API_NAME_GOMP_TARGET_UPDATE)(int device, const void *openmp_target, size_t mapnum,
1116  void **hostaddrs, size_t *sizes, unsigned char *kinds)
1117 {
1118  return;
1119 }
1120 
1121 void
1122 xexpand(KMP_API_NAME_GOMP_TEAMS)(unsigned int num_teams, unsigned int thread_limit)
1123 {
1124  return;
1125 }
1126 #endif // OMP_40_ENABLED
1127 
1128 
1129 /*
1130  The following sections of code create aliases for the GOMP_* functions,
1131  then create versioned symbols using the assembler directive .symver.
1132  This is only pertinent for ELF .so library
1133  xaliasify and xversionify are defined in kmp_ftn_os.h
1134 */
1135 
1136 #ifdef KMP_USE_VERSION_SYMBOLS
1137 
1138 // GOMP_1.0 aliases
1139 xaliasify(KMP_API_NAME_GOMP_ATOMIC_END, 10);
1140 xaliasify(KMP_API_NAME_GOMP_ATOMIC_START, 10);
1141 xaliasify(KMP_API_NAME_GOMP_BARRIER, 10);
1142 xaliasify(KMP_API_NAME_GOMP_CRITICAL_END, 10);
1143 xaliasify(KMP_API_NAME_GOMP_CRITICAL_NAME_END, 10);
1144 xaliasify(KMP_API_NAME_GOMP_CRITICAL_NAME_START, 10);
1145 xaliasify(KMP_API_NAME_GOMP_CRITICAL_START, 10);
1146 xaliasify(KMP_API_NAME_GOMP_LOOP_DYNAMIC_NEXT, 10);
1147 xaliasify(KMP_API_NAME_GOMP_LOOP_DYNAMIC_START, 10);
1148 xaliasify(KMP_API_NAME_GOMP_LOOP_END, 10);
1149 xaliasify(KMP_API_NAME_GOMP_LOOP_END_NOWAIT, 10);
1150 xaliasify(KMP_API_NAME_GOMP_LOOP_GUIDED_NEXT, 10);
1151 xaliasify(KMP_API_NAME_GOMP_LOOP_GUIDED_START, 10);
1152 xaliasify(KMP_API_NAME_GOMP_LOOP_ORDERED_DYNAMIC_NEXT, 10);
1153 xaliasify(KMP_API_NAME_GOMP_LOOP_ORDERED_DYNAMIC_START, 10);
1154 xaliasify(KMP_API_NAME_GOMP_LOOP_ORDERED_GUIDED_NEXT, 10);
1155 xaliasify(KMP_API_NAME_GOMP_LOOP_ORDERED_GUIDED_START, 10);
1156 xaliasify(KMP_API_NAME_GOMP_LOOP_ORDERED_RUNTIME_NEXT, 10);
1157 xaliasify(KMP_API_NAME_GOMP_LOOP_ORDERED_RUNTIME_START, 10);
1158 xaliasify(KMP_API_NAME_GOMP_LOOP_ORDERED_STATIC_NEXT, 10);
1159 xaliasify(KMP_API_NAME_GOMP_LOOP_ORDERED_STATIC_START, 10);
1160 xaliasify(KMP_API_NAME_GOMP_LOOP_RUNTIME_NEXT, 10);
1161 xaliasify(KMP_API_NAME_GOMP_LOOP_RUNTIME_START, 10);
1162 xaliasify(KMP_API_NAME_GOMP_LOOP_STATIC_NEXT, 10);
1163 xaliasify(KMP_API_NAME_GOMP_LOOP_STATIC_START, 10);
1164 xaliasify(KMP_API_NAME_GOMP_ORDERED_END, 10);
1165 xaliasify(KMP_API_NAME_GOMP_ORDERED_START, 10);
1166 xaliasify(KMP_API_NAME_GOMP_PARALLEL_END, 10);
1167 xaliasify(KMP_API_NAME_GOMP_PARALLEL_LOOP_DYNAMIC_START, 10);
1168 xaliasify(KMP_API_NAME_GOMP_PARALLEL_LOOP_GUIDED_START, 10);
1169 xaliasify(KMP_API_NAME_GOMP_PARALLEL_LOOP_RUNTIME_START, 10);
1170 xaliasify(KMP_API_NAME_GOMP_PARALLEL_LOOP_STATIC_START, 10);
1171 xaliasify(KMP_API_NAME_GOMP_PARALLEL_SECTIONS_START, 10);
1172 xaliasify(KMP_API_NAME_GOMP_PARALLEL_START, 10);
1173 xaliasify(KMP_API_NAME_GOMP_SECTIONS_END, 10);
1174 xaliasify(KMP_API_NAME_GOMP_SECTIONS_END_NOWAIT, 10);
1175 xaliasify(KMP_API_NAME_GOMP_SECTIONS_NEXT, 10);
1176 xaliasify(KMP_API_NAME_GOMP_SECTIONS_START, 10);
1177 xaliasify(KMP_API_NAME_GOMP_SINGLE_COPY_END, 10);
1178 xaliasify(KMP_API_NAME_GOMP_SINGLE_COPY_START, 10);
1179 xaliasify(KMP_API_NAME_GOMP_SINGLE_START, 10);
1180 
1181 // GOMP_2.0 aliases
1182 xaliasify(KMP_API_NAME_GOMP_TASK, 20);
1183 xaliasify(KMP_API_NAME_GOMP_TASKWAIT, 20);
1184 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_DYNAMIC_NEXT, 20);
1185 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_DYNAMIC_START, 20);
1186 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_GUIDED_NEXT, 20);
1187 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_GUIDED_START, 20);
1188 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_DYNAMIC_NEXT, 20);
1189 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_DYNAMIC_START, 20);
1190 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_GUIDED_NEXT, 20);
1191 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_GUIDED_START, 20);
1192 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_NEXT, 20);
1193 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_START, 20);
1194 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_STATIC_NEXT, 20);
1195 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_STATIC_START, 20);
1196 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_RUNTIME_NEXT, 20);
1197 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_RUNTIME_START, 20);
1198 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_STATIC_NEXT, 20);
1199 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_STATIC_START, 20);
1200 
1201 // GOMP_3.0 aliases
1202 xaliasify(KMP_API_NAME_GOMP_TASKYIELD, 30);
1203 
1204 // GOMP_4.0 aliases
1205 // The GOMP_parallel* entry points below aren't OpenMP 4.0 related.
1206 #if OMP_40_ENABLED
1207 xaliasify(KMP_API_NAME_GOMP_PARALLEL, 40);
1208 xaliasify(KMP_API_NAME_GOMP_PARALLEL_SECTIONS, 40);
1209 xaliasify(KMP_API_NAME_GOMP_PARALLEL_LOOP_DYNAMIC, 40);
1210 xaliasify(KMP_API_NAME_GOMP_PARALLEL_LOOP_GUIDED, 40);
1211 xaliasify(KMP_API_NAME_GOMP_PARALLEL_LOOP_RUNTIME, 40);
1212 xaliasify(KMP_API_NAME_GOMP_PARALLEL_LOOP_STATIC, 40);
1213 xaliasify(KMP_API_NAME_GOMP_TASKGROUP_START, 40);
1214 xaliasify(KMP_API_NAME_GOMP_TASKGROUP_END, 40);
1215 xaliasify(KMP_API_NAME_GOMP_BARRIER_CANCEL, 40);
1216 xaliasify(KMP_API_NAME_GOMP_CANCEL, 40);
1217 xaliasify(KMP_API_NAME_GOMP_CANCELLATION_POINT, 40);
1218 xaliasify(KMP_API_NAME_GOMP_LOOP_END_CANCEL, 40);
1219 xaliasify(KMP_API_NAME_GOMP_SECTIONS_END_CANCEL, 40);
1220 xaliasify(KMP_API_NAME_GOMP_TARGET, 40);
1221 xaliasify(KMP_API_NAME_GOMP_TARGET_DATA, 40);
1222 xaliasify(KMP_API_NAME_GOMP_TARGET_END_DATA, 40);
1223 xaliasify(KMP_API_NAME_GOMP_TARGET_UPDATE, 40);
1224 xaliasify(KMP_API_NAME_GOMP_TEAMS, 40);
1225 #endif
1226 
1227 // GOMP_1.0 versioned symbols
1228 xversionify(KMP_API_NAME_GOMP_ATOMIC_END, 10, "GOMP_1.0");
1229 xversionify(KMP_API_NAME_GOMP_ATOMIC_START, 10, "GOMP_1.0");
1230 xversionify(KMP_API_NAME_GOMP_BARRIER, 10, "GOMP_1.0");
1231 xversionify(KMP_API_NAME_GOMP_CRITICAL_END, 10, "GOMP_1.0");
1232 xversionify(KMP_API_NAME_GOMP_CRITICAL_NAME_END, 10, "GOMP_1.0");
1233 xversionify(KMP_API_NAME_GOMP_CRITICAL_NAME_START, 10, "GOMP_1.0");
1234 xversionify(KMP_API_NAME_GOMP_CRITICAL_START, 10, "GOMP_1.0");
1235 xversionify(KMP_API_NAME_GOMP_LOOP_DYNAMIC_NEXT, 10, "GOMP_1.0");
1236 xversionify(KMP_API_NAME_GOMP_LOOP_DYNAMIC_START, 10, "GOMP_1.0");
1237 xversionify(KMP_API_NAME_GOMP_LOOP_END, 10, "GOMP_1.0");
1238 xversionify(KMP_API_NAME_GOMP_LOOP_END_NOWAIT, 10, "GOMP_1.0");
1239 xversionify(KMP_API_NAME_GOMP_LOOP_GUIDED_NEXT, 10, "GOMP_1.0");
1240 xversionify(KMP_API_NAME_GOMP_LOOP_GUIDED_START, 10, "GOMP_1.0");
1241 xversionify(KMP_API_NAME_GOMP_LOOP_ORDERED_DYNAMIC_NEXT, 10, "GOMP_1.0");
1242 xversionify(KMP_API_NAME_GOMP_LOOP_ORDERED_DYNAMIC_START, 10, "GOMP_1.0");
1243 xversionify(KMP_API_NAME_GOMP_LOOP_ORDERED_GUIDED_NEXT, 10, "GOMP_1.0");
1244 xversionify(KMP_API_NAME_GOMP_LOOP_ORDERED_GUIDED_START, 10, "GOMP_1.0");
1245 xversionify(KMP_API_NAME_GOMP_LOOP_ORDERED_RUNTIME_NEXT, 10, "GOMP_1.0");
1246 xversionify(KMP_API_NAME_GOMP_LOOP_ORDERED_RUNTIME_START, 10, "GOMP_1.0");
1247 xversionify(KMP_API_NAME_GOMP_LOOP_ORDERED_STATIC_NEXT, 10, "GOMP_1.0");
1248 xversionify(KMP_API_NAME_GOMP_LOOP_ORDERED_STATIC_START, 10, "GOMP_1.0");
1249 xversionify(KMP_API_NAME_GOMP_LOOP_RUNTIME_NEXT, 10, "GOMP_1.0");
1250 xversionify(KMP_API_NAME_GOMP_LOOP_RUNTIME_START, 10, "GOMP_1.0");
1251 xversionify(KMP_API_NAME_GOMP_LOOP_STATIC_NEXT, 10, "GOMP_1.0");
1252 xversionify(KMP_API_NAME_GOMP_LOOP_STATIC_START, 10, "GOMP_1.0");
1253 xversionify(KMP_API_NAME_GOMP_ORDERED_END, 10, "GOMP_1.0");
1254 xversionify(KMP_API_NAME_GOMP_ORDERED_START, 10, "GOMP_1.0");
1255 xversionify(KMP_API_NAME_GOMP_PARALLEL_END, 10, "GOMP_1.0");
1256 xversionify(KMP_API_NAME_GOMP_PARALLEL_LOOP_DYNAMIC_START, 10, "GOMP_1.0");
1257 xversionify(KMP_API_NAME_GOMP_PARALLEL_LOOP_GUIDED_START, 10, "GOMP_1.0");
1258 xversionify(KMP_API_NAME_GOMP_PARALLEL_LOOP_RUNTIME_START, 10, "GOMP_1.0");
1259 xversionify(KMP_API_NAME_GOMP_PARALLEL_LOOP_STATIC_START, 10, "GOMP_1.0");
1260 xversionify(KMP_API_NAME_GOMP_PARALLEL_SECTIONS_START, 10, "GOMP_1.0");
1261 xversionify(KMP_API_NAME_GOMP_PARALLEL_START, 10, "GOMP_1.0");
1262 xversionify(KMP_API_NAME_GOMP_SECTIONS_END, 10, "GOMP_1.0");
1263 xversionify(KMP_API_NAME_GOMP_SECTIONS_END_NOWAIT, 10, "GOMP_1.0");
1264 xversionify(KMP_API_NAME_GOMP_SECTIONS_NEXT, 10, "GOMP_1.0");
1265 xversionify(KMP_API_NAME_GOMP_SECTIONS_START, 10, "GOMP_1.0");
1266 xversionify(KMP_API_NAME_GOMP_SINGLE_COPY_END, 10, "GOMP_1.0");
1267 xversionify(KMP_API_NAME_GOMP_SINGLE_COPY_START, 10, "GOMP_1.0");
1268 xversionify(KMP_API_NAME_GOMP_SINGLE_START, 10, "GOMP_1.0");
1269 
1270 // GOMP_2.0 versioned symbols
1271 xversionify(KMP_API_NAME_GOMP_TASK, 20, "GOMP_2.0");
1272 xversionify(KMP_API_NAME_GOMP_TASKWAIT, 20, "GOMP_2.0");
1273 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_DYNAMIC_NEXT, 20, "GOMP_2.0");
1274 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_DYNAMIC_START, 20, "GOMP_2.0");
1275 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_GUIDED_NEXT, 20, "GOMP_2.0");
1276 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_GUIDED_START, 20, "GOMP_2.0");
1277 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_DYNAMIC_NEXT, 20, "GOMP_2.0");
1278 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_DYNAMIC_START, 20, "GOMP_2.0");
1279 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_GUIDED_NEXT, 20, "GOMP_2.0");
1280 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_GUIDED_START, 20, "GOMP_2.0");
1281 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_NEXT, 20, "GOMP_2.0");
1282 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_START, 20, "GOMP_2.0");
1283 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_STATIC_NEXT, 20, "GOMP_2.0");
1284 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_STATIC_START, 20, "GOMP_2.0");
1285 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_RUNTIME_NEXT, 20, "GOMP_2.0");
1286 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_RUNTIME_START, 20, "GOMP_2.0");
1287 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_STATIC_NEXT, 20, "GOMP_2.0");
1288 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_STATIC_START, 20, "GOMP_2.0");
1289 
1290 // GOMP_3.0 versioned symbols
1291 xversionify(KMP_API_NAME_GOMP_TASKYIELD, 30, "GOMP_3.0");
1292 
1293 // GOMP_4.0 versioned symbols
1294 #if OMP_40_ENABLED
1295 xversionify(KMP_API_NAME_GOMP_PARALLEL, 40, "GOMP_4.0");
1296 xversionify(KMP_API_NAME_GOMP_PARALLEL_SECTIONS, 40, "GOMP_4.0");
1297 xversionify(KMP_API_NAME_GOMP_PARALLEL_LOOP_DYNAMIC, 40, "GOMP_4.0");
1298 xversionify(KMP_API_NAME_GOMP_PARALLEL_LOOP_GUIDED, 40, "GOMP_4.0");
1299 xversionify(KMP_API_NAME_GOMP_PARALLEL_LOOP_RUNTIME, 40, "GOMP_4.0");
1300 xversionify(KMP_API_NAME_GOMP_PARALLEL_LOOP_STATIC, 40, "GOMP_4.0");
1301 xversionify(KMP_API_NAME_GOMP_TASKGROUP_START, 40, "GOMP_4.0");
1302 xversionify(KMP_API_NAME_GOMP_TASKGROUP_END, 40, "GOMP_4.0");
1303 xversionify(KMP_API_NAME_GOMP_BARRIER_CANCEL, 40, "GOMP_4.0");
1304 xversionify(KMP_API_NAME_GOMP_CANCEL, 40, "GOMP_4.0");
1305 xversionify(KMP_API_NAME_GOMP_CANCELLATION_POINT, 40, "GOMP_4.0");
1306 xversionify(KMP_API_NAME_GOMP_LOOP_END_CANCEL, 40, "GOMP_4.0");
1307 xversionify(KMP_API_NAME_GOMP_SECTIONS_END_CANCEL, 40, "GOMP_4.0");
1308 xversionify(KMP_API_NAME_GOMP_TARGET, 40, "GOMP_4.0");
1309 xversionify(KMP_API_NAME_GOMP_TARGET_DATA, 40, "GOMP_4.0");
1310 xversionify(KMP_API_NAME_GOMP_TARGET_END_DATA, 40, "GOMP_4.0");
1311 xversionify(KMP_API_NAME_GOMP_TARGET_UPDATE, 40, "GOMP_4.0");
1312 xversionify(KMP_API_NAME_GOMP_TEAMS, 40, "GOMP_4.0");
1313 #endif
1314 
1315 #endif // KMP_USE_VERSION_SYMBOLS
1316 
1317 #ifdef __cplusplus
1318  } //extern "C"
1319 #endif // __cplusplus
1320 
1321 
KMP_EXPORT void __kmpc_end_ordered(ident_t *, kmp_int32 global_tid)
Definition: kmp_csupport.c:781
KMP_EXPORT void __kmpc_end_serialized_parallel(ident_t *, kmp_int32 global_tid)
Definition: kmp_csupport.c:438
KMP_EXPORT void __kmpc_ordered(ident_t *, kmp_int32 global_tid)
Definition: kmp_csupport.c:745
KMP_EXPORT void __kmpc_critical(ident_t *, kmp_int32 global_tid, kmp_critical_name *)
Definition: kmp.h:221
KMP_EXPORT kmp_int32 __kmpc_ok_to_fork(ident_t *)
Definition: kmp_csupport.c:175
KMP_EXPORT void __kmpc_barrier(ident_t *, kmp_int32 global_tid)
Definition: kmp_csupport.c:646
KMP_EXPORT void __kmpc_end_critical(ident_t *, kmp_int32 global_tid, kmp_critical_name *)
KMP_EXPORT void __kmpc_serialized_parallel(ident_t *, kmp_int32 global_tid)
Definition: kmp_csupport.c:423
sched_type
Definition: kmp.h:323