LLVM OpenMP* Runtime Library
z_Linux_util.cpp
1 /*
2  * z_Linux_util.cpp -- platform specific routines.
3  */
4 
5 //===----------------------------------------------------------------------===//
6 //
7 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
8 // See https://llvm.org/LICENSE.txt for license information.
9 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "kmp.h"
14 #include "kmp_affinity.h"
15 #include "kmp_i18n.h"
16 #include "kmp_io.h"
17 #include "kmp_itt.h"
18 #include "kmp_lock.h"
19 #include "kmp_stats.h"
20 #include "kmp_str.h"
21 #include "kmp_wait_release.h"
22 #include "kmp_wrapper_getpid.h"
23 
24 #if !KMP_OS_DRAGONFLY && !KMP_OS_FREEBSD && !KMP_OS_NETBSD && !KMP_OS_OPENBSD
25 #include <alloca.h>
26 #endif
27 #include <math.h> // HUGE_VAL.
28 #if KMP_OS_LINUX
29 #include <semaphore.h>
30 #endif // KMP_OS_LINUX
31 #include <sys/resource.h>
32 #include <sys/syscall.h>
33 #include <sys/time.h>
34 #include <sys/times.h>
35 #include <unistd.h>
36 
37 #if KMP_OS_LINUX
38 #include <sys/sysinfo.h>
39 #if KMP_USE_FUTEX
40 // We should really include <futex.h>, but that causes compatibility problems on
41 // different Linux* OS distributions that either require that you include (or
42 // break when you try to include) <pci/types.h>. Since all we need is the two
43 // macros below (which are part of the kernel ABI, so can't change) we just
44 // define the constants here and don't include <futex.h>
45 #ifndef FUTEX_WAIT
46 #define FUTEX_WAIT 0
47 #endif
48 #ifndef FUTEX_WAKE
49 #define FUTEX_WAKE 1
50 #endif
51 #endif
52 #elif KMP_OS_DARWIN
53 #include <mach/mach.h>
54 #include <sys/sysctl.h>
55 #elif KMP_OS_DRAGONFLY || KMP_OS_FREEBSD
56 #include <sys/types.h>
57 #include <sys/sysctl.h>
58 #include <sys/user.h>
59 #include <pthread_np.h>
60 #elif KMP_OS_NETBSD || KMP_OS_OPENBSD
61 #include <sys/types.h>
62 #include <sys/sysctl.h>
63 #endif
64 
65 #include <ctype.h>
66 #include <dirent.h>
67 #include <fcntl.h>
68 
69 struct kmp_sys_timer {
70  struct timespec start;
71 };
72 
73 // Convert timespec to nanoseconds.
74 #define TS2NS(timespec) \
75  (((timespec).tv_sec * (long int)1e9) + (timespec).tv_nsec)
76 
77 static struct kmp_sys_timer __kmp_sys_timer_data;
78 
79 #if KMP_HANDLE_SIGNALS
80 typedef void (*sig_func_t)(int);
81 STATIC_EFI2_WORKAROUND struct sigaction __kmp_sighldrs[NSIG];
82 static sigset_t __kmp_sigset;
83 #endif
84 
85 static int __kmp_init_runtime = FALSE;
86 
87 static int __kmp_fork_count = 0;
88 
89 static pthread_condattr_t __kmp_suspend_cond_attr;
90 static pthread_mutexattr_t __kmp_suspend_mutex_attr;
91 
92 static kmp_cond_align_t __kmp_wait_cv;
93 static kmp_mutex_align_t __kmp_wait_mx;
94 
95 kmp_uint64 __kmp_ticks_per_msec = 1000000;
96 
97 #ifdef DEBUG_SUSPEND
98 static void __kmp_print_cond(char *buffer, kmp_cond_align_t *cond) {
99  KMP_SNPRINTF(buffer, 128, "(cond (lock (%ld, %d)), (descr (%p)))",
100  cond->c_cond.__c_lock.__status, cond->c_cond.__c_lock.__spinlock,
101  cond->c_cond.__c_waiting);
102 }
103 #endif
104 
105 #if ((KMP_OS_LINUX || KMP_OS_FREEBSD) && KMP_AFFINITY_SUPPORTED)
106 
107 /* Affinity support */
108 
109 void __kmp_affinity_bind_thread(int which) {
110  KMP_ASSERT2(KMP_AFFINITY_CAPABLE(),
111  "Illegal set affinity operation when not capable");
112 
113  kmp_affin_mask_t *mask;
114  KMP_CPU_ALLOC_ON_STACK(mask);
115  KMP_CPU_ZERO(mask);
116  KMP_CPU_SET(which, mask);
117  __kmp_set_system_affinity(mask, TRUE);
118  KMP_CPU_FREE_FROM_STACK(mask);
119 }
120 
121 /* Determine if we can access affinity functionality on this version of
122  * Linux* OS by checking __NR_sched_{get,set}affinity system calls, and set
123  * __kmp_affin_mask_size to the appropriate value (0 means not capable). */
124 void __kmp_affinity_determine_capable(const char *env_var) {
125  // Check and see if the OS supports thread affinity.
126 
127 #if KMP_OS_LINUX
128 #define KMP_CPU_SET_SIZE_LIMIT (1024 * 1024)
129 #define KMP_CPU_SET_TRY_SIZE CACHE_LINE
130 #elif KMP_OS_FREEBSD
131 #define KMP_CPU_SET_SIZE_LIMIT (sizeof(cpuset_t))
132 #endif
133 
134  int verbose = __kmp_affinity.flags.verbose;
135  int warnings = __kmp_affinity.flags.warnings;
136  enum affinity_type type = __kmp_affinity.type;
137 
138 #if KMP_OS_LINUX
139  long gCode;
140  unsigned char *buf;
141  buf = (unsigned char *)KMP_INTERNAL_MALLOC(KMP_CPU_SET_SIZE_LIMIT);
142 
143  // If the syscall returns a suggestion for the size,
144  // then we don't have to search for an appropriate size.
145  gCode = syscall(__NR_sched_getaffinity, 0, KMP_CPU_SET_TRY_SIZE, buf);
146  KA_TRACE(30, ("__kmp_affinity_determine_capable: "
147  "initial getaffinity call returned %ld errno = %d\n",
148  gCode, errno));
149 
150  if (gCode < 0 && errno != EINVAL) {
151  // System call not supported
152  if (verbose ||
153  (warnings && (type != affinity_none) && (type != affinity_default) &&
154  (type != affinity_disabled))) {
155  int error = errno;
156  kmp_msg_t err_code = KMP_ERR(error);
157  __kmp_msg(kmp_ms_warning, KMP_MSG(GetAffSysCallNotSupported, env_var),
158  err_code, __kmp_msg_null);
159  if (__kmp_generate_warnings == kmp_warnings_off) {
160  __kmp_str_free(&err_code.str);
161  }
162  }
163  KMP_AFFINITY_DISABLE();
164  KMP_INTERNAL_FREE(buf);
165  return;
166  } else if (gCode > 0) {
167  // The optimal situation: the OS returns the size of the buffer it expects.
168  KMP_AFFINITY_ENABLE(gCode);
169  KA_TRACE(10, ("__kmp_affinity_determine_capable: "
170  "affinity supported (mask size %d)\n",
171  (int)__kmp_affin_mask_size));
172  KMP_INTERNAL_FREE(buf);
173  return;
174  }
175 
176  // Call the getaffinity system call repeatedly with increasing set sizes
177  // until we succeed, or reach an upper bound on the search.
178  KA_TRACE(30, ("__kmp_affinity_determine_capable: "
179  "searching for proper set size\n"));
180  int size;
181  for (size = 1; size <= KMP_CPU_SET_SIZE_LIMIT; size *= 2) {
182  gCode = syscall(__NR_sched_getaffinity, 0, size, buf);
183  KA_TRACE(30, ("__kmp_affinity_determine_capable: "
184  "getaffinity for mask size %ld returned %ld errno = %d\n",
185  size, gCode, errno));
186 
187  if (gCode < 0) {
188  if (errno == ENOSYS) {
189  // We shouldn't get here
190  KA_TRACE(30, ("__kmp_affinity_determine_capable: "
191  "inconsistent OS call behavior: errno == ENOSYS for mask "
192  "size %d\n",
193  size));
194  if (verbose ||
195  (warnings && (type != affinity_none) &&
196  (type != affinity_default) && (type != affinity_disabled))) {
197  int error = errno;
198  kmp_msg_t err_code = KMP_ERR(error);
199  __kmp_msg(kmp_ms_warning, KMP_MSG(GetAffSysCallNotSupported, env_var),
200  err_code, __kmp_msg_null);
201  if (__kmp_generate_warnings == kmp_warnings_off) {
202  __kmp_str_free(&err_code.str);
203  }
204  }
205  KMP_AFFINITY_DISABLE();
206  KMP_INTERNAL_FREE(buf);
207  return;
208  }
209  continue;
210  }
211 
212  KMP_AFFINITY_ENABLE(gCode);
213  KA_TRACE(10, ("__kmp_affinity_determine_capable: "
214  "affinity supported (mask size %d)\n",
215  (int)__kmp_affin_mask_size));
216  KMP_INTERNAL_FREE(buf);
217  return;
218  }
219 #elif KMP_OS_FREEBSD
220  long gCode;
221  unsigned char *buf;
222  buf = (unsigned char *)KMP_INTERNAL_MALLOC(KMP_CPU_SET_SIZE_LIMIT);
223  gCode = pthread_getaffinity_np(pthread_self(), KMP_CPU_SET_SIZE_LIMIT,
224  reinterpret_cast<cpuset_t *>(buf));
225  KA_TRACE(30, ("__kmp_affinity_determine_capable: "
226  "initial getaffinity call returned %d errno = %d\n",
227  gCode, errno));
228  if (gCode == 0) {
229  KMP_AFFINITY_ENABLE(KMP_CPU_SET_SIZE_LIMIT);
230  KA_TRACE(10, ("__kmp_affinity_determine_capable: "
231  "affinity supported (mask size %d)\n",
232  (int)__kmp_affin_mask_size));
233  KMP_INTERNAL_FREE(buf);
234  return;
235  }
236 #endif
237  KMP_INTERNAL_FREE(buf);
238 
239  // Affinity is not supported
240  KMP_AFFINITY_DISABLE();
241  KA_TRACE(10, ("__kmp_affinity_determine_capable: "
242  "cannot determine mask size - affinity not supported\n"));
243  if (verbose || (warnings && (type != affinity_none) &&
244  (type != affinity_default) && (type != affinity_disabled))) {
245  KMP_WARNING(AffCantGetMaskSize, env_var);
246  }
247 }
248 
249 #endif // KMP_OS_LINUX && KMP_AFFINITY_SUPPORTED
250 
251 #if KMP_USE_FUTEX
252 
253 int __kmp_futex_determine_capable() {
254  int loc = 0;
255  long rc = syscall(__NR_futex, &loc, FUTEX_WAKE, 1, NULL, NULL, 0);
256  int retval = (rc == 0) || (errno != ENOSYS);
257 
258  KA_TRACE(10,
259  ("__kmp_futex_determine_capable: rc = %d errno = %d\n", rc, errno));
260  KA_TRACE(10, ("__kmp_futex_determine_capable: futex syscall%s supported\n",
261  retval ? "" : " not"));
262 
263  return retval;
264 }
265 
266 #endif // KMP_USE_FUTEX
267 
268 #if (KMP_ARCH_X86 || KMP_ARCH_X86_64) && (!KMP_ASM_INTRINS)
269 /* Only 32-bit "add-exchange" instruction on IA-32 architecture causes us to
270  use compare_and_store for these routines */
271 
272 kmp_int8 __kmp_test_then_or8(volatile kmp_int8 *p, kmp_int8 d) {
273  kmp_int8 old_value, new_value;
274 
275  old_value = TCR_1(*p);
276  new_value = old_value | d;
277 
278  while (!KMP_COMPARE_AND_STORE_REL8(p, old_value, new_value)) {
279  KMP_CPU_PAUSE();
280  old_value = TCR_1(*p);
281  new_value = old_value | d;
282  }
283  return old_value;
284 }
285 
286 kmp_int8 __kmp_test_then_and8(volatile kmp_int8 *p, kmp_int8 d) {
287  kmp_int8 old_value, new_value;
288 
289  old_value = TCR_1(*p);
290  new_value = old_value & d;
291 
292  while (!KMP_COMPARE_AND_STORE_REL8(p, old_value, new_value)) {
293  KMP_CPU_PAUSE();
294  old_value = TCR_1(*p);
295  new_value = old_value & d;
296  }
297  return old_value;
298 }
299 
300 kmp_uint32 __kmp_test_then_or32(volatile kmp_uint32 *p, kmp_uint32 d) {
301  kmp_uint32 old_value, new_value;
302 
303  old_value = TCR_4(*p);
304  new_value = old_value | d;
305 
306  while (!KMP_COMPARE_AND_STORE_REL32(p, old_value, new_value)) {
307  KMP_CPU_PAUSE();
308  old_value = TCR_4(*p);
309  new_value = old_value | d;
310  }
311  return old_value;
312 }
313 
314 kmp_uint32 __kmp_test_then_and32(volatile kmp_uint32 *p, kmp_uint32 d) {
315  kmp_uint32 old_value, new_value;
316 
317  old_value = TCR_4(*p);
318  new_value = old_value & d;
319 
320  while (!KMP_COMPARE_AND_STORE_REL32(p, old_value, new_value)) {
321  KMP_CPU_PAUSE();
322  old_value = TCR_4(*p);
323  new_value = old_value & d;
324  }
325  return old_value;
326 }
327 
328 #if KMP_ARCH_X86
329 kmp_int8 __kmp_test_then_add8(volatile kmp_int8 *p, kmp_int8 d) {
330  kmp_int8 old_value, new_value;
331 
332  old_value = TCR_1(*p);
333  new_value = old_value + d;
334 
335  while (!KMP_COMPARE_AND_STORE_REL8(p, old_value, new_value)) {
336  KMP_CPU_PAUSE();
337  old_value = TCR_1(*p);
338  new_value = old_value + d;
339  }
340  return old_value;
341 }
342 
343 kmp_int64 __kmp_test_then_add64(volatile kmp_int64 *p, kmp_int64 d) {
344  kmp_int64 old_value, new_value;
345 
346  old_value = TCR_8(*p);
347  new_value = old_value + d;
348 
349  while (!KMP_COMPARE_AND_STORE_REL64(p, old_value, new_value)) {
350  KMP_CPU_PAUSE();
351  old_value = TCR_8(*p);
352  new_value = old_value + d;
353  }
354  return old_value;
355 }
356 #endif /* KMP_ARCH_X86 */
357 
358 kmp_uint64 __kmp_test_then_or64(volatile kmp_uint64 *p, kmp_uint64 d) {
359  kmp_uint64 old_value, new_value;
360 
361  old_value = TCR_8(*p);
362  new_value = old_value | d;
363  while (!KMP_COMPARE_AND_STORE_REL64(p, old_value, new_value)) {
364  KMP_CPU_PAUSE();
365  old_value = TCR_8(*p);
366  new_value = old_value | d;
367  }
368  return old_value;
369 }
370 
371 kmp_uint64 __kmp_test_then_and64(volatile kmp_uint64 *p, kmp_uint64 d) {
372  kmp_uint64 old_value, new_value;
373 
374  old_value = TCR_8(*p);
375  new_value = old_value & d;
376  while (!KMP_COMPARE_AND_STORE_REL64(p, old_value, new_value)) {
377  KMP_CPU_PAUSE();
378  old_value = TCR_8(*p);
379  new_value = old_value & d;
380  }
381  return old_value;
382 }
383 
384 #endif /* (KMP_ARCH_X86 || KMP_ARCH_X86_64) && (! KMP_ASM_INTRINS) */
385 
386 void __kmp_terminate_thread(int gtid) {
387  int status;
388  kmp_info_t *th = __kmp_threads[gtid];
389 
390  if (!th)
391  return;
392 
393 #ifdef KMP_CANCEL_THREADS
394  KA_TRACE(10, ("__kmp_terminate_thread: kill (%d)\n", gtid));
395  status = pthread_cancel(th->th.th_info.ds.ds_thread);
396  if (status != 0 && status != ESRCH) {
397  __kmp_fatal(KMP_MSG(CantTerminateWorkerThread), KMP_ERR(status),
398  __kmp_msg_null);
399  }
400 #endif
401  KMP_YIELD(TRUE);
402 } //
403 
404 /* Set thread stack info according to values returned by pthread_getattr_np().
405  If values are unreasonable, assume call failed and use incremental stack
406  refinement method instead. Returns TRUE if the stack parameters could be
407  determined exactly, FALSE if incremental refinement is necessary. */
408 static kmp_int32 __kmp_set_stack_info(int gtid, kmp_info_t *th) {
409  int stack_data;
410 #if KMP_OS_LINUX || KMP_OS_DRAGONFLY || KMP_OS_FREEBSD || KMP_OS_NETBSD || \
411  KMP_OS_HURD
412  pthread_attr_t attr;
413  int status;
414  size_t size = 0;
415  void *addr = 0;
416 
417  /* Always do incremental stack refinement for ubermaster threads since the
418  initial thread stack range can be reduced by sibling thread creation so
419  pthread_attr_getstack may cause thread gtid aliasing */
420  if (!KMP_UBER_GTID(gtid)) {
421 
422  /* Fetch the real thread attributes */
423  status = pthread_attr_init(&attr);
424  KMP_CHECK_SYSFAIL("pthread_attr_init", status);
425 #if KMP_OS_DRAGONFLY || KMP_OS_FREEBSD || KMP_OS_NETBSD
426  status = pthread_attr_get_np(pthread_self(), &attr);
427  KMP_CHECK_SYSFAIL("pthread_attr_get_np", status);
428 #else
429  status = pthread_getattr_np(pthread_self(), &attr);
430  KMP_CHECK_SYSFAIL("pthread_getattr_np", status);
431 #endif
432  status = pthread_attr_getstack(&attr, &addr, &size);
433  KMP_CHECK_SYSFAIL("pthread_attr_getstack", status);
434  KA_TRACE(60,
435  ("__kmp_set_stack_info: T#%d pthread_attr_getstack returned size:"
436  " %lu, low addr: %p\n",
437  gtid, size, addr));
438  status = pthread_attr_destroy(&attr);
439  KMP_CHECK_SYSFAIL("pthread_attr_destroy", status);
440  }
441 
442  if (size != 0 && addr != 0) { // was stack parameter determination successful?
443  /* Store the correct base and size */
444  TCW_PTR(th->th.th_info.ds.ds_stackbase, (((char *)addr) + size));
445  TCW_PTR(th->th.th_info.ds.ds_stacksize, size);
446  TCW_4(th->th.th_info.ds.ds_stackgrow, FALSE);
447  return TRUE;
448  }
449 #endif /* KMP_OS_LINUX || KMP_OS_DRAGONFLY || KMP_OS_FREEBSD || KMP_OS_NETBSD \
450  || KMP_OS_HURD */
451  /* Use incremental refinement starting from initial conservative estimate */
452  TCW_PTR(th->th.th_info.ds.ds_stacksize, 0);
453  TCW_PTR(th->th.th_info.ds.ds_stackbase, &stack_data);
454  TCW_4(th->th.th_info.ds.ds_stackgrow, TRUE);
455  return FALSE;
456 }
457 
458 static void *__kmp_launch_worker(void *thr) {
459  int status, old_type, old_state;
460 #ifdef KMP_BLOCK_SIGNALS
461  sigset_t new_set, old_set;
462 #endif /* KMP_BLOCK_SIGNALS */
463  void *exit_val;
464 #if KMP_OS_LINUX || KMP_OS_DRAGONFLY || KMP_OS_FREEBSD || KMP_OS_NETBSD || \
465  KMP_OS_OPENBSD || KMP_OS_HURD
466  void *volatile padding = 0;
467 #endif
468  int gtid;
469 
470  gtid = ((kmp_info_t *)thr)->th.th_info.ds.ds_gtid;
471  __kmp_gtid_set_specific(gtid);
472 #ifdef KMP_TDATA_GTID
473  __kmp_gtid = gtid;
474 #endif
475 #if KMP_STATS_ENABLED
476  // set thread local index to point to thread-specific stats
477  __kmp_stats_thread_ptr = ((kmp_info_t *)thr)->th.th_stats;
478  __kmp_stats_thread_ptr->startLife();
479  KMP_SET_THREAD_STATE(IDLE);
480  KMP_INIT_PARTITIONED_TIMERS(OMP_idle);
481 #endif
482 
483 #if USE_ITT_BUILD
484  __kmp_itt_thread_name(gtid);
485 #endif /* USE_ITT_BUILD */
486 
487 #if KMP_AFFINITY_SUPPORTED
488  __kmp_affinity_set_init_mask(gtid, FALSE);
489 #endif
490 
491 #ifdef KMP_CANCEL_THREADS
492  status = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old_type);
493  KMP_CHECK_SYSFAIL("pthread_setcanceltype", status);
494  // josh todo: isn't PTHREAD_CANCEL_ENABLE default for newly-created threads?
495  status = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_state);
496  KMP_CHECK_SYSFAIL("pthread_setcancelstate", status);
497 #endif
498 
499 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
500  // Set FP control regs to be a copy of the parallel initialization thread's.
501  __kmp_clear_x87_fpu_status_word();
502  __kmp_load_x87_fpu_control_word(&__kmp_init_x87_fpu_control_word);
503  __kmp_load_mxcsr(&__kmp_init_mxcsr);
504 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
505 
506 #ifdef KMP_BLOCK_SIGNALS
507  status = sigfillset(&new_set);
508  KMP_CHECK_SYSFAIL_ERRNO("sigfillset", status);
509  status = pthread_sigmask(SIG_BLOCK, &new_set, &old_set);
510  KMP_CHECK_SYSFAIL("pthread_sigmask", status);
511 #endif /* KMP_BLOCK_SIGNALS */
512 
513 #if KMP_OS_LINUX || KMP_OS_DRAGONFLY || KMP_OS_FREEBSD || KMP_OS_NETBSD || \
514  KMP_OS_OPENBSD
515  if (__kmp_stkoffset > 0 && gtid > 0) {
516  padding = KMP_ALLOCA(gtid * __kmp_stkoffset);
517  (void)padding;
518  }
519 #endif
520 
521  KMP_MB();
522  __kmp_set_stack_info(gtid, (kmp_info_t *)thr);
523 
524  __kmp_check_stack_overlap((kmp_info_t *)thr);
525 
526  exit_val = __kmp_launch_thread((kmp_info_t *)thr);
527 
528 #ifdef KMP_BLOCK_SIGNALS
529  status = pthread_sigmask(SIG_SETMASK, &old_set, NULL);
530  KMP_CHECK_SYSFAIL("pthread_sigmask", status);
531 #endif /* KMP_BLOCK_SIGNALS */
532 
533  return exit_val;
534 }
535 
536 #if KMP_USE_MONITOR
537 /* The monitor thread controls all of the threads in the complex */
538 
539 static void *__kmp_launch_monitor(void *thr) {
540  int status, old_type, old_state;
541 #ifdef KMP_BLOCK_SIGNALS
542  sigset_t new_set;
543 #endif /* KMP_BLOCK_SIGNALS */
544  struct timespec interval;
545 
546  KMP_MB(); /* Flush all pending memory write invalidates. */
547 
548  KA_TRACE(10, ("__kmp_launch_monitor: #1 launched\n"));
549 
550  /* register us as the monitor thread */
551  __kmp_gtid_set_specific(KMP_GTID_MONITOR);
552 #ifdef KMP_TDATA_GTID
553  __kmp_gtid = KMP_GTID_MONITOR;
554 #endif
555 
556  KMP_MB();
557 
558 #if USE_ITT_BUILD
559  // Instruct Intel(R) Threading Tools to ignore monitor thread.
560  __kmp_itt_thread_ignore();
561 #endif /* USE_ITT_BUILD */
562 
563  __kmp_set_stack_info(((kmp_info_t *)thr)->th.th_info.ds.ds_gtid,
564  (kmp_info_t *)thr);
565 
566  __kmp_check_stack_overlap((kmp_info_t *)thr);
567 
568 #ifdef KMP_CANCEL_THREADS
569  status = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old_type);
570  KMP_CHECK_SYSFAIL("pthread_setcanceltype", status);
571  // josh todo: isn't PTHREAD_CANCEL_ENABLE default for newly-created threads?
572  status = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_state);
573  KMP_CHECK_SYSFAIL("pthread_setcancelstate", status);
574 #endif
575 
576 #if KMP_REAL_TIME_FIX
577  // This is a potential fix which allows application with real-time scheduling
578  // policy work. However, decision about the fix is not made yet, so it is
579  // disabled by default.
580  { // Are program started with real-time scheduling policy?
581  int sched = sched_getscheduler(0);
582  if (sched == SCHED_FIFO || sched == SCHED_RR) {
583  // Yes, we are a part of real-time application. Try to increase the
584  // priority of the monitor.
585  struct sched_param param;
586  int max_priority = sched_get_priority_max(sched);
587  int rc;
588  KMP_WARNING(RealTimeSchedNotSupported);
589  sched_getparam(0, &param);
590  if (param.sched_priority < max_priority) {
591  param.sched_priority += 1;
592  rc = sched_setscheduler(0, sched, &param);
593  if (rc != 0) {
594  int error = errno;
595  kmp_msg_t err_code = KMP_ERR(error);
596  __kmp_msg(kmp_ms_warning, KMP_MSG(CantChangeMonitorPriority),
597  err_code, KMP_MSG(MonitorWillStarve), __kmp_msg_null);
598  if (__kmp_generate_warnings == kmp_warnings_off) {
599  __kmp_str_free(&err_code.str);
600  }
601  }
602  } else {
603  // We cannot abort here, because number of CPUs may be enough for all
604  // the threads, including the monitor thread, so application could
605  // potentially work...
606  __kmp_msg(kmp_ms_warning, KMP_MSG(RunningAtMaxPriority),
607  KMP_MSG(MonitorWillStarve), KMP_HNT(RunningAtMaxPriority),
608  __kmp_msg_null);
609  }
610  }
611  // AC: free thread that waits for monitor started
612  TCW_4(__kmp_global.g.g_time.dt.t_value, 0);
613  }
614 #endif // KMP_REAL_TIME_FIX
615 
616  KMP_MB(); /* Flush all pending memory write invalidates. */
617 
618  if (__kmp_monitor_wakeups == 1) {
619  interval.tv_sec = 1;
620  interval.tv_nsec = 0;
621  } else {
622  interval.tv_sec = 0;
623  interval.tv_nsec = (KMP_NSEC_PER_SEC / __kmp_monitor_wakeups);
624  }
625 
626  KA_TRACE(10, ("__kmp_launch_monitor: #2 monitor\n"));
627 
628  while (!TCR_4(__kmp_global.g.g_done)) {
629  struct timespec now;
630  struct timeval tval;
631 
632  /* This thread monitors the state of the system */
633 
634  KA_TRACE(15, ("__kmp_launch_monitor: update\n"));
635 
636  status = gettimeofday(&tval, NULL);
637  KMP_CHECK_SYSFAIL_ERRNO("gettimeofday", status);
638  TIMEVAL_TO_TIMESPEC(&tval, &now);
639 
640  now.tv_sec += interval.tv_sec;
641  now.tv_nsec += interval.tv_nsec;
642 
643  if (now.tv_nsec >= KMP_NSEC_PER_SEC) {
644  now.tv_sec += 1;
645  now.tv_nsec -= KMP_NSEC_PER_SEC;
646  }
647 
648  status = pthread_mutex_lock(&__kmp_wait_mx.m_mutex);
649  KMP_CHECK_SYSFAIL("pthread_mutex_lock", status);
650  // AC: the monitor should not fall asleep if g_done has been set
651  if (!TCR_4(__kmp_global.g.g_done)) { // check once more under mutex
652  status = pthread_cond_timedwait(&__kmp_wait_cv.c_cond,
653  &__kmp_wait_mx.m_mutex, &now);
654  if (status != 0) {
655  if (status != ETIMEDOUT && status != EINTR) {
656  KMP_SYSFAIL("pthread_cond_timedwait", status);
657  }
658  }
659  }
660  status = pthread_mutex_unlock(&__kmp_wait_mx.m_mutex);
661  KMP_CHECK_SYSFAIL("pthread_mutex_unlock", status);
662 
663  TCW_4(__kmp_global.g.g_time.dt.t_value,
664  TCR_4(__kmp_global.g.g_time.dt.t_value) + 1);
665 
666  KMP_MB(); /* Flush all pending memory write invalidates. */
667  }
668 
669  KA_TRACE(10, ("__kmp_launch_monitor: #3 cleanup\n"));
670 
671 #ifdef KMP_BLOCK_SIGNALS
672  status = sigfillset(&new_set);
673  KMP_CHECK_SYSFAIL_ERRNO("sigfillset", status);
674  status = pthread_sigmask(SIG_UNBLOCK, &new_set, NULL);
675  KMP_CHECK_SYSFAIL("pthread_sigmask", status);
676 #endif /* KMP_BLOCK_SIGNALS */
677 
678  KA_TRACE(10, ("__kmp_launch_monitor: #4 finished\n"));
679 
680  if (__kmp_global.g.g_abort != 0) {
681  /* now we need to terminate the worker threads */
682  /* the value of t_abort is the signal we caught */
683 
684  int gtid;
685 
686  KA_TRACE(10, ("__kmp_launch_monitor: #5 terminate sig=%d\n",
687  __kmp_global.g.g_abort));
688 
689  /* terminate the OpenMP worker threads */
690  /* TODO this is not valid for sibling threads!!
691  * the uber master might not be 0 anymore.. */
692  for (gtid = 1; gtid < __kmp_threads_capacity; ++gtid)
693  __kmp_terminate_thread(gtid);
694 
695  __kmp_cleanup();
696 
697  KA_TRACE(10, ("__kmp_launch_monitor: #6 raise sig=%d\n",
698  __kmp_global.g.g_abort));
699 
700  if (__kmp_global.g.g_abort > 0)
701  raise(__kmp_global.g.g_abort);
702  }
703 
704  KA_TRACE(10, ("__kmp_launch_monitor: #7 exit\n"));
705 
706  return thr;
707 }
708 #endif // KMP_USE_MONITOR
709 
710 void __kmp_create_worker(int gtid, kmp_info_t *th, size_t stack_size) {
711  pthread_t handle;
712  pthread_attr_t thread_attr;
713  int status;
714 
715  th->th.th_info.ds.ds_gtid = gtid;
716 
717 #if KMP_STATS_ENABLED
718  // sets up worker thread stats
719  __kmp_acquire_tas_lock(&__kmp_stats_lock, gtid);
720 
721  // th->th.th_stats is used to transfer thread-specific stats-pointer to
722  // __kmp_launch_worker. So when thread is created (goes into
723  // __kmp_launch_worker) it will set its thread local pointer to
724  // th->th.th_stats
725  if (!KMP_UBER_GTID(gtid)) {
726  th->th.th_stats = __kmp_stats_list->push_back(gtid);
727  } else {
728  // For root threads, __kmp_stats_thread_ptr is set in __kmp_register_root(),
729  // so set the th->th.th_stats field to it.
730  th->th.th_stats = __kmp_stats_thread_ptr;
731  }
732  __kmp_release_tas_lock(&__kmp_stats_lock, gtid);
733 
734 #endif // KMP_STATS_ENABLED
735 
736  if (KMP_UBER_GTID(gtid)) {
737  KA_TRACE(10, ("__kmp_create_worker: uber thread (%d)\n", gtid));
738  th->th.th_info.ds.ds_thread = pthread_self();
739  __kmp_set_stack_info(gtid, th);
740  __kmp_check_stack_overlap(th);
741  return;
742  }
743 
744  KA_TRACE(10, ("__kmp_create_worker: try to create thread (%d)\n", gtid));
745 
746  KMP_MB(); /* Flush all pending memory write invalidates. */
747 
748 #ifdef KMP_THREAD_ATTR
749  status = pthread_attr_init(&thread_attr);
750  if (status != 0) {
751  __kmp_fatal(KMP_MSG(CantInitThreadAttrs), KMP_ERR(status), __kmp_msg_null);
752  }
753  status = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE);
754  if (status != 0) {
755  __kmp_fatal(KMP_MSG(CantSetWorkerState), KMP_ERR(status), __kmp_msg_null);
756  }
757 
758  /* Set stack size for this thread now.
759  The multiple of 2 is there because on some machines, requesting an unusual
760  stacksize causes the thread to have an offset before the dummy alloca()
761  takes place to create the offset. Since we want the user to have a
762  sufficient stacksize AND support a stack offset, we alloca() twice the
763  offset so that the upcoming alloca() does not eliminate any premade offset,
764  and also gives the user the stack space they requested for all threads */
765  stack_size += gtid * __kmp_stkoffset * 2;
766 
767  KA_TRACE(10, ("__kmp_create_worker: T#%d, default stacksize = %lu bytes, "
768  "__kmp_stksize = %lu bytes, final stacksize = %lu bytes\n",
769  gtid, KMP_DEFAULT_STKSIZE, __kmp_stksize, stack_size));
770 
771 #ifdef _POSIX_THREAD_ATTR_STACKSIZE
772  status = pthread_attr_setstacksize(&thread_attr, stack_size);
773 #ifdef KMP_BACKUP_STKSIZE
774  if (status != 0) {
775  if (!__kmp_env_stksize) {
776  stack_size = KMP_BACKUP_STKSIZE + gtid * __kmp_stkoffset;
777  __kmp_stksize = KMP_BACKUP_STKSIZE;
778  KA_TRACE(10, ("__kmp_create_worker: T#%d, default stacksize = %lu bytes, "
779  "__kmp_stksize = %lu bytes, (backup) final stacksize = %lu "
780  "bytes\n",
781  gtid, KMP_DEFAULT_STKSIZE, __kmp_stksize, stack_size));
782  status = pthread_attr_setstacksize(&thread_attr, stack_size);
783  }
784  }
785 #endif /* KMP_BACKUP_STKSIZE */
786  if (status != 0) {
787  __kmp_fatal(KMP_MSG(CantSetWorkerStackSize, stack_size), KMP_ERR(status),
788  KMP_HNT(ChangeWorkerStackSize), __kmp_msg_null);
789  }
790 #endif /* _POSIX_THREAD_ATTR_STACKSIZE */
791 
792 #endif /* KMP_THREAD_ATTR */
793 
794  status =
795  pthread_create(&handle, &thread_attr, __kmp_launch_worker, (void *)th);
796  if (status != 0 || !handle) { // ??? Why do we check handle??
797 #ifdef _POSIX_THREAD_ATTR_STACKSIZE
798  if (status == EINVAL) {
799  __kmp_fatal(KMP_MSG(CantSetWorkerStackSize, stack_size), KMP_ERR(status),
800  KMP_HNT(IncreaseWorkerStackSize), __kmp_msg_null);
801  }
802  if (status == ENOMEM) {
803  __kmp_fatal(KMP_MSG(CantSetWorkerStackSize, stack_size), KMP_ERR(status),
804  KMP_HNT(DecreaseWorkerStackSize), __kmp_msg_null);
805  }
806 #endif /* _POSIX_THREAD_ATTR_STACKSIZE */
807  if (status == EAGAIN) {
808  __kmp_fatal(KMP_MSG(NoResourcesForWorkerThread), KMP_ERR(status),
809  KMP_HNT(Decrease_NUM_THREADS), __kmp_msg_null);
810  }
811  KMP_SYSFAIL("pthread_create", status);
812  }
813 
814  th->th.th_info.ds.ds_thread = handle;
815 
816 #ifdef KMP_THREAD_ATTR
817  status = pthread_attr_destroy(&thread_attr);
818  if (status) {
819  kmp_msg_t err_code = KMP_ERR(status);
820  __kmp_msg(kmp_ms_warning, KMP_MSG(CantDestroyThreadAttrs), err_code,
821  __kmp_msg_null);
822  if (__kmp_generate_warnings == kmp_warnings_off) {
823  __kmp_str_free(&err_code.str);
824  }
825  }
826 #endif /* KMP_THREAD_ATTR */
827 
828  KMP_MB(); /* Flush all pending memory write invalidates. */
829 
830  KA_TRACE(10, ("__kmp_create_worker: done creating thread (%d)\n", gtid));
831 
832 } // __kmp_create_worker
833 
834 #if KMP_USE_MONITOR
835 void __kmp_create_monitor(kmp_info_t *th) {
836  pthread_t handle;
837  pthread_attr_t thread_attr;
838  size_t size;
839  int status;
840  int auto_adj_size = FALSE;
841 
842  if (__kmp_dflt_blocktime == KMP_MAX_BLOCKTIME) {
843  // We don't need monitor thread in case of MAX_BLOCKTIME
844  KA_TRACE(10, ("__kmp_create_monitor: skipping monitor thread because of "
845  "MAX blocktime\n"));
846  th->th.th_info.ds.ds_tid = 0; // this makes reap_monitor no-op
847  th->th.th_info.ds.ds_gtid = 0;
848  return;
849  }
850  KA_TRACE(10, ("__kmp_create_monitor: try to create monitor\n"));
851 
852  KMP_MB(); /* Flush all pending memory write invalidates. */
853 
854  th->th.th_info.ds.ds_tid = KMP_GTID_MONITOR;
855  th->th.th_info.ds.ds_gtid = KMP_GTID_MONITOR;
856 #if KMP_REAL_TIME_FIX
857  TCW_4(__kmp_global.g.g_time.dt.t_value,
858  -1); // Will use it for synchronization a bit later.
859 #else
860  TCW_4(__kmp_global.g.g_time.dt.t_value, 0);
861 #endif // KMP_REAL_TIME_FIX
862 
863 #ifdef KMP_THREAD_ATTR
864  if (__kmp_monitor_stksize == 0) {
865  __kmp_monitor_stksize = KMP_DEFAULT_MONITOR_STKSIZE;
866  auto_adj_size = TRUE;
867  }
868  status = pthread_attr_init(&thread_attr);
869  if (status != 0) {
870  __kmp_fatal(KMP_MSG(CantInitThreadAttrs), KMP_ERR(status), __kmp_msg_null);
871  }
872  status = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE);
873  if (status != 0) {
874  __kmp_fatal(KMP_MSG(CantSetMonitorState), KMP_ERR(status), __kmp_msg_null);
875  }
876 
877 #ifdef _POSIX_THREAD_ATTR_STACKSIZE
878  status = pthread_attr_getstacksize(&thread_attr, &size);
879  KMP_CHECK_SYSFAIL("pthread_attr_getstacksize", status);
880 #else
881  size = __kmp_sys_min_stksize;
882 #endif /* _POSIX_THREAD_ATTR_STACKSIZE */
883 #endif /* KMP_THREAD_ATTR */
884 
885  if (__kmp_monitor_stksize == 0) {
886  __kmp_monitor_stksize = KMP_DEFAULT_MONITOR_STKSIZE;
887  }
888  if (__kmp_monitor_stksize < __kmp_sys_min_stksize) {
889  __kmp_monitor_stksize = __kmp_sys_min_stksize;
890  }
891 
892  KA_TRACE(10, ("__kmp_create_monitor: default stacksize = %lu bytes,"
893  "requested stacksize = %lu bytes\n",
894  size, __kmp_monitor_stksize));
895 
896 retry:
897 
898 /* Set stack size for this thread now. */
899 #ifdef _POSIX_THREAD_ATTR_STACKSIZE
900  KA_TRACE(10, ("__kmp_create_monitor: setting stacksize = %lu bytes,",
901  __kmp_monitor_stksize));
902  status = pthread_attr_setstacksize(&thread_attr, __kmp_monitor_stksize);
903  if (status != 0) {
904  if (auto_adj_size) {
905  __kmp_monitor_stksize *= 2;
906  goto retry;
907  }
908  kmp_msg_t err_code = KMP_ERR(status);
909  __kmp_msg(kmp_ms_warning, // should this be fatal? BB
910  KMP_MSG(CantSetMonitorStackSize, (long int)__kmp_monitor_stksize),
911  err_code, KMP_HNT(ChangeMonitorStackSize), __kmp_msg_null);
912  if (__kmp_generate_warnings == kmp_warnings_off) {
913  __kmp_str_free(&err_code.str);
914  }
915  }
916 #endif /* _POSIX_THREAD_ATTR_STACKSIZE */
917 
918  status =
919  pthread_create(&handle, &thread_attr, __kmp_launch_monitor, (void *)th);
920 
921  if (status != 0) {
922 #ifdef _POSIX_THREAD_ATTR_STACKSIZE
923  if (status == EINVAL) {
924  if (auto_adj_size && (__kmp_monitor_stksize < (size_t)0x40000000)) {
925  __kmp_monitor_stksize *= 2;
926  goto retry;
927  }
928  __kmp_fatal(KMP_MSG(CantSetMonitorStackSize, __kmp_monitor_stksize),
929  KMP_ERR(status), KMP_HNT(IncreaseMonitorStackSize),
930  __kmp_msg_null);
931  }
932  if (status == ENOMEM) {
933  __kmp_fatal(KMP_MSG(CantSetMonitorStackSize, __kmp_monitor_stksize),
934  KMP_ERR(status), KMP_HNT(DecreaseMonitorStackSize),
935  __kmp_msg_null);
936  }
937 #endif /* _POSIX_THREAD_ATTR_STACKSIZE */
938  if (status == EAGAIN) {
939  __kmp_fatal(KMP_MSG(NoResourcesForMonitorThread), KMP_ERR(status),
940  KMP_HNT(DecreaseNumberOfThreadsInUse), __kmp_msg_null);
941  }
942  KMP_SYSFAIL("pthread_create", status);
943  }
944 
945  th->th.th_info.ds.ds_thread = handle;
946 
947 #if KMP_REAL_TIME_FIX
948  // Wait for the monitor thread is really started and set its *priority*.
949  KMP_DEBUG_ASSERT(sizeof(kmp_uint32) ==
950  sizeof(__kmp_global.g.g_time.dt.t_value));
951  __kmp_wait_4((kmp_uint32 volatile *)&__kmp_global.g.g_time.dt.t_value, -1,
952  &__kmp_neq_4, NULL);
953 #endif // KMP_REAL_TIME_FIX
954 
955 #ifdef KMP_THREAD_ATTR
956  status = pthread_attr_destroy(&thread_attr);
957  if (status != 0) {
958  kmp_msg_t err_code = KMP_ERR(status);
959  __kmp_msg(kmp_ms_warning, KMP_MSG(CantDestroyThreadAttrs), err_code,
960  __kmp_msg_null);
961  if (__kmp_generate_warnings == kmp_warnings_off) {
962  __kmp_str_free(&err_code.str);
963  }
964  }
965 #endif
966 
967  KMP_MB(); /* Flush all pending memory write invalidates. */
968 
969  KA_TRACE(10, ("__kmp_create_monitor: monitor created %#.8lx\n",
970  th->th.th_info.ds.ds_thread));
971 
972 } // __kmp_create_monitor
973 #endif // KMP_USE_MONITOR
974 
975 void __kmp_exit_thread(int exit_status) {
976  pthread_exit((void *)(intptr_t)exit_status);
977 } // __kmp_exit_thread
978 
979 #if KMP_USE_MONITOR
980 void __kmp_resume_monitor();
981 
982 extern "C" void __kmp_reap_monitor(kmp_info_t *th) {
983  int status;
984  void *exit_val;
985 
986  KA_TRACE(10, ("__kmp_reap_monitor: try to reap monitor thread with handle"
987  " %#.8lx\n",
988  th->th.th_info.ds.ds_thread));
989 
990  // If monitor has been created, its tid and gtid should be KMP_GTID_MONITOR.
991  // If both tid and gtid are 0, it means the monitor did not ever start.
992  // If both tid and gtid are KMP_GTID_DNE, the monitor has been shut down.
993  KMP_DEBUG_ASSERT(th->th.th_info.ds.ds_tid == th->th.th_info.ds.ds_gtid);
994  if (th->th.th_info.ds.ds_gtid != KMP_GTID_MONITOR) {
995  KA_TRACE(10, ("__kmp_reap_monitor: monitor did not start, returning\n"));
996  return;
997  }
998 
999  KMP_MB(); /* Flush all pending memory write invalidates. */
1000 
1001  /* First, check to see whether the monitor thread exists to wake it up. This
1002  is to avoid performance problem when the monitor sleeps during
1003  blocktime-size interval */
1004 
1005  status = pthread_kill(th->th.th_info.ds.ds_thread, 0);
1006  if (status != ESRCH) {
1007  __kmp_resume_monitor(); // Wake up the monitor thread
1008  }
1009  KA_TRACE(10, ("__kmp_reap_monitor: try to join with monitor\n"));
1010  status = pthread_join(th->th.th_info.ds.ds_thread, &exit_val);
1011  if (exit_val != th) {
1012  __kmp_fatal(KMP_MSG(ReapMonitorError), KMP_ERR(status), __kmp_msg_null);
1013  }
1014 
1015  th->th.th_info.ds.ds_tid = KMP_GTID_DNE;
1016  th->th.th_info.ds.ds_gtid = KMP_GTID_DNE;
1017 
1018  KA_TRACE(10, ("__kmp_reap_monitor: done reaping monitor thread with handle"
1019  " %#.8lx\n",
1020  th->th.th_info.ds.ds_thread));
1021 
1022  KMP_MB(); /* Flush all pending memory write invalidates. */
1023 }
1024 #else
1025 // Empty symbol to export (see exports_so.txt) when
1026 // monitor thread feature is disabled
1027 extern "C" void __kmp_reap_monitor(kmp_info_t *th) {
1028  (void)th;
1029 }
1030 #endif // KMP_USE_MONITOR
1031 
1032 void __kmp_reap_worker(kmp_info_t *th) {
1033  int status;
1034  void *exit_val;
1035 
1036  KMP_MB(); /* Flush all pending memory write invalidates. */
1037 
1038  KA_TRACE(
1039  10, ("__kmp_reap_worker: try to reap T#%d\n", th->th.th_info.ds.ds_gtid));
1040 
1041  status = pthread_join(th->th.th_info.ds.ds_thread, &exit_val);
1042 #ifdef KMP_DEBUG
1043  /* Don't expose these to the user until we understand when they trigger */
1044  if (status != 0) {
1045  __kmp_fatal(KMP_MSG(ReapWorkerError), KMP_ERR(status), __kmp_msg_null);
1046  }
1047  if (exit_val != th) {
1048  KA_TRACE(10, ("__kmp_reap_worker: worker T#%d did not reap properly, "
1049  "exit_val = %p\n",
1050  th->th.th_info.ds.ds_gtid, exit_val));
1051  }
1052 #else
1053  (void)status; // unused variable
1054 #endif /* KMP_DEBUG */
1055 
1056  KA_TRACE(10, ("__kmp_reap_worker: done reaping T#%d\n",
1057  th->th.th_info.ds.ds_gtid));
1058 
1059  KMP_MB(); /* Flush all pending memory write invalidates. */
1060 }
1061 
1062 #if KMP_HANDLE_SIGNALS
1063 
1064 static void __kmp_null_handler(int signo) {
1065  // Do nothing, for doing SIG_IGN-type actions.
1066 } // __kmp_null_handler
1067 
1068 static void __kmp_team_handler(int signo) {
1069  if (__kmp_global.g.g_abort == 0) {
1070 /* Stage 1 signal handler, let's shut down all of the threads */
1071 #ifdef KMP_DEBUG
1072  __kmp_debug_printf("__kmp_team_handler: caught signal = %d\n", signo);
1073 #endif
1074  switch (signo) {
1075  case SIGHUP:
1076  case SIGINT:
1077  case SIGQUIT:
1078  case SIGILL:
1079  case SIGABRT:
1080  case SIGFPE:
1081  case SIGBUS:
1082  case SIGSEGV:
1083 #ifdef SIGSYS
1084  case SIGSYS:
1085 #endif
1086  case SIGTERM:
1087  if (__kmp_debug_buf) {
1088  __kmp_dump_debug_buffer();
1089  }
1090  __kmp_unregister_library(); // cleanup shared memory
1091  KMP_MB(); // Flush all pending memory write invalidates.
1092  TCW_4(__kmp_global.g.g_abort, signo);
1093  KMP_MB(); // Flush all pending memory write invalidates.
1094  TCW_4(__kmp_global.g.g_done, TRUE);
1095  KMP_MB(); // Flush all pending memory write invalidates.
1096  break;
1097  default:
1098 #ifdef KMP_DEBUG
1099  __kmp_debug_printf("__kmp_team_handler: unknown signal type");
1100 #endif
1101  break;
1102  }
1103  }
1104 } // __kmp_team_handler
1105 
1106 static void __kmp_sigaction(int signum, const struct sigaction *act,
1107  struct sigaction *oldact) {
1108  int rc = sigaction(signum, act, oldact);
1109  KMP_CHECK_SYSFAIL_ERRNO("sigaction", rc);
1110 }
1111 
1112 static void __kmp_install_one_handler(int sig, sig_func_t handler_func,
1113  int parallel_init) {
1114  KMP_MB(); // Flush all pending memory write invalidates.
1115  KB_TRACE(60,
1116  ("__kmp_install_one_handler( %d, ..., %d )\n", sig, parallel_init));
1117  if (parallel_init) {
1118  struct sigaction new_action;
1119  struct sigaction old_action;
1120  new_action.sa_handler = handler_func;
1121  new_action.sa_flags = 0;
1122  sigfillset(&new_action.sa_mask);
1123  __kmp_sigaction(sig, &new_action, &old_action);
1124  if (old_action.sa_handler == __kmp_sighldrs[sig].sa_handler) {
1125  sigaddset(&__kmp_sigset, sig);
1126  } else {
1127  // Restore/keep user's handler if one previously installed.
1128  __kmp_sigaction(sig, &old_action, NULL);
1129  }
1130  } else {
1131  // Save initial/system signal handlers to see if user handlers installed.
1132  __kmp_sigaction(sig, NULL, &__kmp_sighldrs[sig]);
1133  }
1134  KMP_MB(); // Flush all pending memory write invalidates.
1135 } // __kmp_install_one_handler
1136 
1137 static void __kmp_remove_one_handler(int sig) {
1138  KB_TRACE(60, ("__kmp_remove_one_handler( %d )\n", sig));
1139  if (sigismember(&__kmp_sigset, sig)) {
1140  struct sigaction old;
1141  KMP_MB(); // Flush all pending memory write invalidates.
1142  __kmp_sigaction(sig, &__kmp_sighldrs[sig], &old);
1143  if ((old.sa_handler != __kmp_team_handler) &&
1144  (old.sa_handler != __kmp_null_handler)) {
1145  // Restore the users signal handler.
1146  KB_TRACE(10, ("__kmp_remove_one_handler: oops, not our handler, "
1147  "restoring: sig=%d\n",
1148  sig));
1149  __kmp_sigaction(sig, &old, NULL);
1150  }
1151  sigdelset(&__kmp_sigset, sig);
1152  KMP_MB(); // Flush all pending memory write invalidates.
1153  }
1154 } // __kmp_remove_one_handler
1155 
1156 void __kmp_install_signals(int parallel_init) {
1157  KB_TRACE(10, ("__kmp_install_signals( %d )\n", parallel_init));
1158  if (__kmp_handle_signals || !parallel_init) {
1159  // If ! parallel_init, we do not install handlers, just save original
1160  // handlers. Let us do it even __handle_signals is 0.
1161  sigemptyset(&__kmp_sigset);
1162  __kmp_install_one_handler(SIGHUP, __kmp_team_handler, parallel_init);
1163  __kmp_install_one_handler(SIGINT, __kmp_team_handler, parallel_init);
1164  __kmp_install_one_handler(SIGQUIT, __kmp_team_handler, parallel_init);
1165  __kmp_install_one_handler(SIGILL, __kmp_team_handler, parallel_init);
1166  __kmp_install_one_handler(SIGABRT, __kmp_team_handler, parallel_init);
1167  __kmp_install_one_handler(SIGFPE, __kmp_team_handler, parallel_init);
1168  __kmp_install_one_handler(SIGBUS, __kmp_team_handler, parallel_init);
1169  __kmp_install_one_handler(SIGSEGV, __kmp_team_handler, parallel_init);
1170 #ifdef SIGSYS
1171  __kmp_install_one_handler(SIGSYS, __kmp_team_handler, parallel_init);
1172 #endif // SIGSYS
1173  __kmp_install_one_handler(SIGTERM, __kmp_team_handler, parallel_init);
1174 #ifdef SIGPIPE
1175  __kmp_install_one_handler(SIGPIPE, __kmp_team_handler, parallel_init);
1176 #endif // SIGPIPE
1177  }
1178 } // __kmp_install_signals
1179 
1180 void __kmp_remove_signals(void) {
1181  int sig;
1182  KB_TRACE(10, ("__kmp_remove_signals()\n"));
1183  for (sig = 1; sig < NSIG; ++sig) {
1184  __kmp_remove_one_handler(sig);
1185  }
1186 } // __kmp_remove_signals
1187 
1188 #endif // KMP_HANDLE_SIGNALS
1189 
1190 void __kmp_enable(int new_state) {
1191 #ifdef KMP_CANCEL_THREADS
1192  int status, old_state;
1193  status = pthread_setcancelstate(new_state, &old_state);
1194  KMP_CHECK_SYSFAIL("pthread_setcancelstate", status);
1195  KMP_DEBUG_ASSERT(old_state == PTHREAD_CANCEL_DISABLE);
1196 #endif
1197 }
1198 
1199 void __kmp_disable(int *old_state) {
1200 #ifdef KMP_CANCEL_THREADS
1201  int status;
1202  status = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, old_state);
1203  KMP_CHECK_SYSFAIL("pthread_setcancelstate", status);
1204 #endif
1205 }
1206 
1207 static void __kmp_atfork_prepare(void) {
1208  __kmp_acquire_bootstrap_lock(&__kmp_initz_lock);
1209  __kmp_acquire_bootstrap_lock(&__kmp_forkjoin_lock);
1210 }
1211 
1212 static void __kmp_atfork_parent(void) {
1213  __kmp_release_bootstrap_lock(&__kmp_forkjoin_lock);
1214  __kmp_release_bootstrap_lock(&__kmp_initz_lock);
1215 }
1216 
1217 /* Reset the library so execution in the child starts "all over again" with
1218  clean data structures in initial states. Don't worry about freeing memory
1219  allocated by parent, just abandon it to be safe. */
1220 static void __kmp_atfork_child(void) {
1221  __kmp_release_bootstrap_lock(&__kmp_forkjoin_lock);
1222  __kmp_release_bootstrap_lock(&__kmp_initz_lock);
1223  /* TODO make sure this is done right for nested/sibling */
1224  // ATT: Memory leaks are here? TODO: Check it and fix.
1225  /* KMP_ASSERT( 0 ); */
1226 
1227  ++__kmp_fork_count;
1228 
1229 #if KMP_AFFINITY_SUPPORTED
1230 #if KMP_OS_LINUX || KMP_OS_FREEBSD
1231  // reset the affinity in the child to the initial thread
1232  // affinity in the parent
1233  kmp_set_thread_affinity_mask_initial();
1234 #endif
1235  // Set default not to bind threads tightly in the child (we're expecting
1236  // over-subscription after the fork and this can improve things for
1237  // scripting languages that use OpenMP inside process-parallel code).
1238  if (__kmp_nested_proc_bind.bind_types != NULL) {
1239  __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
1240  }
1241  for (kmp_affinity_t *affinity : __kmp_affinities)
1242  *affinity = KMP_AFFINITY_INIT(affinity->env_var);
1243  __kmp_affin_fullMask = nullptr;
1244  __kmp_affin_origMask = nullptr;
1245 #endif // KMP_AFFINITY_SUPPORTED
1246 
1247 #if KMP_USE_MONITOR
1248  __kmp_init_monitor = 0;
1249 #endif
1250  __kmp_init_parallel = FALSE;
1251  __kmp_init_middle = FALSE;
1252  __kmp_init_serial = FALSE;
1253  TCW_4(__kmp_init_gtid, FALSE);
1254  __kmp_init_common = FALSE;
1255 
1256  TCW_4(__kmp_init_user_locks, FALSE);
1257 #if !KMP_USE_DYNAMIC_LOCK
1258  __kmp_user_lock_table.used = 1;
1259  __kmp_user_lock_table.allocated = 0;
1260  __kmp_user_lock_table.table = NULL;
1261  __kmp_lock_blocks = NULL;
1262 #endif
1263 
1264  __kmp_all_nth = 0;
1265  TCW_4(__kmp_nth, 0);
1266 
1267  __kmp_thread_pool = NULL;
1268  __kmp_thread_pool_insert_pt = NULL;
1269  __kmp_team_pool = NULL;
1270 
1271  /* Must actually zero all the *cache arguments passed to __kmpc_threadprivate
1272  here so threadprivate doesn't use stale data */
1273  KA_TRACE(10, ("__kmp_atfork_child: checking cache address list %p\n",
1274  __kmp_threadpriv_cache_list));
1275 
1276  while (__kmp_threadpriv_cache_list != NULL) {
1277 
1278  if (*__kmp_threadpriv_cache_list->addr != NULL) {
1279  KC_TRACE(50, ("__kmp_atfork_child: zeroing cache at address %p\n",
1280  &(*__kmp_threadpriv_cache_list->addr)));
1281 
1282  *__kmp_threadpriv_cache_list->addr = NULL;
1283  }
1284  __kmp_threadpriv_cache_list = __kmp_threadpriv_cache_list->next;
1285  }
1286 
1287  __kmp_init_runtime = FALSE;
1288 
1289  /* reset statically initialized locks */
1290  __kmp_init_bootstrap_lock(&__kmp_initz_lock);
1291  __kmp_init_bootstrap_lock(&__kmp_stdio_lock);
1292  __kmp_init_bootstrap_lock(&__kmp_console_lock);
1293  __kmp_init_bootstrap_lock(&__kmp_task_team_lock);
1294 
1295 #if USE_ITT_BUILD
1296  __kmp_itt_reset(); // reset ITT's global state
1297 #endif /* USE_ITT_BUILD */
1298 
1299  {
1300  // Child process often get terminated without any use of OpenMP. That might
1301  // cause mapped shared memory file to be left unattended. Thus we postpone
1302  // library registration till middle initialization in the child process.
1303  __kmp_need_register_serial = FALSE;
1304  __kmp_serial_initialize();
1305  }
1306 
1307  /* This is necessary to make sure no stale data is left around */
1308  /* AC: customers complain that we use unsafe routines in the atfork
1309  handler. Mathworks: dlsym() is unsafe. We call dlsym and dlopen
1310  in dynamic_link when check the presence of shared tbbmalloc library.
1311  Suggestion is to make the library initialization lazier, similar
1312  to what done for __kmpc_begin(). */
1313  // TODO: synchronize all static initializations with regular library
1314  // startup; look at kmp_global.cpp and etc.
1315  //__kmp_internal_begin ();
1316 }
1317 
1318 void __kmp_register_atfork(void) {
1319  if (__kmp_need_register_atfork) {
1320  int status = pthread_atfork(__kmp_atfork_prepare, __kmp_atfork_parent,
1321  __kmp_atfork_child);
1322  KMP_CHECK_SYSFAIL("pthread_atfork", status);
1323  __kmp_need_register_atfork = FALSE;
1324  }
1325 }
1326 
1327 void __kmp_suspend_initialize(void) {
1328  int status;
1329  status = pthread_mutexattr_init(&__kmp_suspend_mutex_attr);
1330  KMP_CHECK_SYSFAIL("pthread_mutexattr_init", status);
1331  status = pthread_condattr_init(&__kmp_suspend_cond_attr);
1332  KMP_CHECK_SYSFAIL("pthread_condattr_init", status);
1333 }
1334 
1335 void __kmp_suspend_initialize_thread(kmp_info_t *th) {
1336  int old_value = KMP_ATOMIC_LD_RLX(&th->th.th_suspend_init_count);
1337  int new_value = __kmp_fork_count + 1;
1338  // Return if already initialized
1339  if (old_value == new_value)
1340  return;
1341  // Wait, then return if being initialized
1342  if (old_value == -1 || !__kmp_atomic_compare_store(
1343  &th->th.th_suspend_init_count, old_value, -1)) {
1344  while (KMP_ATOMIC_LD_ACQ(&th->th.th_suspend_init_count) != new_value) {
1345  KMP_CPU_PAUSE();
1346  }
1347  } else {
1348  // Claim to be the initializer and do initializations
1349  int status;
1350  status = pthread_cond_init(&th->th.th_suspend_cv.c_cond,
1351  &__kmp_suspend_cond_attr);
1352  KMP_CHECK_SYSFAIL("pthread_cond_init", status);
1353  status = pthread_mutex_init(&th->th.th_suspend_mx.m_mutex,
1354  &__kmp_suspend_mutex_attr);
1355  KMP_CHECK_SYSFAIL("pthread_mutex_init", status);
1356  KMP_ATOMIC_ST_REL(&th->th.th_suspend_init_count, new_value);
1357  }
1358 }
1359 
1360 void __kmp_suspend_uninitialize_thread(kmp_info_t *th) {
1361  if (KMP_ATOMIC_LD_ACQ(&th->th.th_suspend_init_count) > __kmp_fork_count) {
1362  /* this means we have initialize the suspension pthread objects for this
1363  thread in this instance of the process */
1364  int status;
1365 
1366  status = pthread_cond_destroy(&th->th.th_suspend_cv.c_cond);
1367  if (status != 0 && status != EBUSY) {
1368  KMP_SYSFAIL("pthread_cond_destroy", status);
1369  }
1370  status = pthread_mutex_destroy(&th->th.th_suspend_mx.m_mutex);
1371  if (status != 0 && status != EBUSY) {
1372  KMP_SYSFAIL("pthread_mutex_destroy", status);
1373  }
1374  --th->th.th_suspend_init_count;
1375  KMP_DEBUG_ASSERT(KMP_ATOMIC_LD_RLX(&th->th.th_suspend_init_count) ==
1376  __kmp_fork_count);
1377  }
1378 }
1379 
1380 // return true if lock obtained, false otherwise
1381 int __kmp_try_suspend_mx(kmp_info_t *th) {
1382  return (pthread_mutex_trylock(&th->th.th_suspend_mx.m_mutex) == 0);
1383 }
1384 
1385 void __kmp_lock_suspend_mx(kmp_info_t *th) {
1386  int status = pthread_mutex_lock(&th->th.th_suspend_mx.m_mutex);
1387  KMP_CHECK_SYSFAIL("pthread_mutex_lock", status);
1388 }
1389 
1390 void __kmp_unlock_suspend_mx(kmp_info_t *th) {
1391  int status = pthread_mutex_unlock(&th->th.th_suspend_mx.m_mutex);
1392  KMP_CHECK_SYSFAIL("pthread_mutex_unlock", status);
1393 }
1394 
1395 /* This routine puts the calling thread to sleep after setting the
1396  sleep bit for the indicated flag variable to true. */
1397 template <class C>
1398 static inline void __kmp_suspend_template(int th_gtid, C *flag) {
1399  KMP_TIME_DEVELOPER_PARTITIONED_BLOCK(USER_suspend);
1400  kmp_info_t *th = __kmp_threads[th_gtid];
1401  int status;
1402  typename C::flag_t old_spin;
1403 
1404  KF_TRACE(30, ("__kmp_suspend_template: T#%d enter for flag = %p\n", th_gtid,
1405  flag->get()));
1406 
1407  __kmp_suspend_initialize_thread(th);
1408 
1409  __kmp_lock_suspend_mx(th);
1410 
1411  KF_TRACE(10, ("__kmp_suspend_template: T#%d setting sleep bit for spin(%p)\n",
1412  th_gtid, flag->get()));
1413 
1414  /* TODO: shouldn't this use release semantics to ensure that
1415  __kmp_suspend_initialize_thread gets called first? */
1416  old_spin = flag->set_sleeping();
1417  TCW_PTR(th->th.th_sleep_loc, (void *)flag);
1418  th->th.th_sleep_loc_type = flag->get_type();
1419  if (__kmp_dflt_blocktime == KMP_MAX_BLOCKTIME &&
1420  __kmp_pause_status != kmp_soft_paused) {
1421  flag->unset_sleeping();
1422  TCW_PTR(th->th.th_sleep_loc, NULL);
1423  th->th.th_sleep_loc_type = flag_unset;
1424  __kmp_unlock_suspend_mx(th);
1425  return;
1426  }
1427  KF_TRACE(5, ("__kmp_suspend_template: T#%d set sleep bit for spin(%p)==%x,"
1428  " was %x\n",
1429  th_gtid, flag->get(), flag->load(), old_spin));
1430 
1431  if (flag->done_check_val(old_spin) || flag->done_check()) {
1432  flag->unset_sleeping();
1433  TCW_PTR(th->th.th_sleep_loc, NULL);
1434  th->th.th_sleep_loc_type = flag_unset;
1435  KF_TRACE(5, ("__kmp_suspend_template: T#%d false alarm, reset sleep bit "
1436  "for spin(%p)\n",
1437  th_gtid, flag->get()));
1438  } else {
1439  /* Encapsulate in a loop as the documentation states that this may
1440  "with low probability" return when the condition variable has
1441  not been signaled or broadcast */
1442  int deactivated = FALSE;
1443 
1444  while (flag->is_sleeping()) {
1445 #ifdef DEBUG_SUSPEND
1446  char buffer[128];
1447  __kmp_suspend_count++;
1448  __kmp_print_cond(buffer, &th->th.th_suspend_cv);
1449  __kmp_printf("__kmp_suspend_template: suspending T#%d: %s\n", th_gtid,
1450  buffer);
1451 #endif
1452  // Mark the thread as no longer active (only in the first iteration of the
1453  // loop).
1454  if (!deactivated) {
1455  th->th.th_active = FALSE;
1456  if (th->th.th_active_in_pool) {
1457  th->th.th_active_in_pool = FALSE;
1458  KMP_ATOMIC_DEC(&__kmp_thread_pool_active_nth);
1459  KMP_DEBUG_ASSERT(TCR_4(__kmp_thread_pool_active_nth) >= 0);
1460  }
1461  deactivated = TRUE;
1462  }
1463 
1464  KMP_DEBUG_ASSERT(th->th.th_sleep_loc);
1465  KMP_DEBUG_ASSERT(flag->get_type() == th->th.th_sleep_loc_type);
1466 
1467 #if USE_SUSPEND_TIMEOUT
1468  struct timespec now;
1469  struct timeval tval;
1470  int msecs;
1471 
1472  status = gettimeofday(&tval, NULL);
1473  KMP_CHECK_SYSFAIL_ERRNO("gettimeofday", status);
1474  TIMEVAL_TO_TIMESPEC(&tval, &now);
1475 
1476  msecs = (4 * __kmp_dflt_blocktime) + 200;
1477  now.tv_sec += msecs / 1000;
1478  now.tv_nsec += (msecs % 1000) * 1000;
1479 
1480  KF_TRACE(15, ("__kmp_suspend_template: T#%d about to perform "
1481  "pthread_cond_timedwait\n",
1482  th_gtid));
1483  status = pthread_cond_timedwait(&th->th.th_suspend_cv.c_cond,
1484  &th->th.th_suspend_mx.m_mutex, &now);
1485 #else
1486  KF_TRACE(15, ("__kmp_suspend_template: T#%d about to perform"
1487  " pthread_cond_wait\n",
1488  th_gtid));
1489  status = pthread_cond_wait(&th->th.th_suspend_cv.c_cond,
1490  &th->th.th_suspend_mx.m_mutex);
1491 #endif // USE_SUSPEND_TIMEOUT
1492 
1493  if ((status != 0) && (status != EINTR) && (status != ETIMEDOUT)) {
1494  KMP_SYSFAIL("pthread_cond_wait", status);
1495  }
1496 
1497  KMP_DEBUG_ASSERT(flag->get_type() == flag->get_ptr_type());
1498 
1499  if (!flag->is_sleeping() &&
1500  ((status == EINTR) || (status == ETIMEDOUT))) {
1501  // if interrupt or timeout, and thread is no longer sleeping, we need to
1502  // make sure sleep_loc gets reset; however, this shouldn't be needed if
1503  // we woke up with resume
1504  flag->unset_sleeping();
1505  TCW_PTR(th->th.th_sleep_loc, NULL);
1506  th->th.th_sleep_loc_type = flag_unset;
1507  }
1508 #ifdef KMP_DEBUG
1509  if (status == ETIMEDOUT) {
1510  if (flag->is_sleeping()) {
1511  KF_TRACE(100,
1512  ("__kmp_suspend_template: T#%d timeout wakeup\n", th_gtid));
1513  } else {
1514  KF_TRACE(2, ("__kmp_suspend_template: T#%d timeout wakeup, sleep bit "
1515  "not set!\n",
1516  th_gtid));
1517  TCW_PTR(th->th.th_sleep_loc, NULL);
1518  th->th.th_sleep_loc_type = flag_unset;
1519  }
1520  } else if (flag->is_sleeping()) {
1521  KF_TRACE(100,
1522  ("__kmp_suspend_template: T#%d spurious wakeup\n", th_gtid));
1523  }
1524 #endif
1525  } // while
1526 
1527  // Mark the thread as active again (if it was previous marked as inactive)
1528  if (deactivated) {
1529  th->th.th_active = TRUE;
1530  if (TCR_4(th->th.th_in_pool)) {
1531  KMP_ATOMIC_INC(&__kmp_thread_pool_active_nth);
1532  th->th.th_active_in_pool = TRUE;
1533  }
1534  }
1535  }
1536  // We may have had the loop variable set before entering the loop body;
1537  // so we need to reset sleep_loc.
1538  TCW_PTR(th->th.th_sleep_loc, NULL);
1539  th->th.th_sleep_loc_type = flag_unset;
1540 
1541  KMP_DEBUG_ASSERT(!flag->is_sleeping());
1542  KMP_DEBUG_ASSERT(!th->th.th_sleep_loc);
1543 #ifdef DEBUG_SUSPEND
1544  {
1545  char buffer[128];
1546  __kmp_print_cond(buffer, &th->th.th_suspend_cv);
1547  __kmp_printf("__kmp_suspend_template: T#%d has awakened: %s\n", th_gtid,
1548  buffer);
1549  }
1550 #endif
1551 
1552  __kmp_unlock_suspend_mx(th);
1553  KF_TRACE(30, ("__kmp_suspend_template: T#%d exit\n", th_gtid));
1554 }
1555 
1556 template <bool C, bool S>
1557 void __kmp_suspend_32(int th_gtid, kmp_flag_32<C, S> *flag) {
1558  __kmp_suspend_template(th_gtid, flag);
1559 }
1560 template <bool C, bool S>
1561 void __kmp_suspend_64(int th_gtid, kmp_flag_64<C, S> *flag) {
1562  __kmp_suspend_template(th_gtid, flag);
1563 }
1564 template <bool C, bool S>
1565 void __kmp_atomic_suspend_64(int th_gtid, kmp_atomic_flag_64<C, S> *flag) {
1566  __kmp_suspend_template(th_gtid, flag);
1567 }
1568 void __kmp_suspend_oncore(int th_gtid, kmp_flag_oncore *flag) {
1569  __kmp_suspend_template(th_gtid, flag);
1570 }
1571 
1572 template void __kmp_suspend_32<false, false>(int, kmp_flag_32<false, false> *);
1573 template void __kmp_suspend_64<false, true>(int, kmp_flag_64<false, true> *);
1574 template void __kmp_suspend_64<true, false>(int, kmp_flag_64<true, false> *);
1575 template void
1576 __kmp_atomic_suspend_64<false, true>(int, kmp_atomic_flag_64<false, true> *);
1577 template void
1578 __kmp_atomic_suspend_64<true, false>(int, kmp_atomic_flag_64<true, false> *);
1579 
1580 /* This routine signals the thread specified by target_gtid to wake up
1581  after setting the sleep bit indicated by the flag argument to FALSE.
1582  The target thread must already have called __kmp_suspend_template() */
1583 template <class C>
1584 static inline void __kmp_resume_template(int target_gtid, C *flag) {
1585  KMP_TIME_DEVELOPER_PARTITIONED_BLOCK(USER_resume);
1586  kmp_info_t *th = __kmp_threads[target_gtid];
1587  int status;
1588 
1589 #ifdef KMP_DEBUG
1590  int gtid = TCR_4(__kmp_init_gtid) ? __kmp_get_gtid() : -1;
1591 #endif
1592 
1593  KF_TRACE(30, ("__kmp_resume_template: T#%d wants to wakeup T#%d enter\n",
1594  gtid, target_gtid));
1595  KMP_DEBUG_ASSERT(gtid != target_gtid);
1596 
1597  __kmp_suspend_initialize_thread(th);
1598 
1599  __kmp_lock_suspend_mx(th);
1600 
1601  if (!flag || flag != th->th.th_sleep_loc) {
1602  // coming from __kmp_null_resume_wrapper, or thread is now sleeping on a
1603  // different location; wake up at new location
1604  flag = (C *)CCAST(void *, th->th.th_sleep_loc);
1605  }
1606 
1607  // First, check if the flag is null or its type has changed. If so, someone
1608  // else woke it up.
1609  if (!flag) { // Thread doesn't appear to be sleeping on anything
1610  KF_TRACE(5, ("__kmp_resume_template: T#%d exiting, thread T#%d already "
1611  "awake: flag(%p)\n",
1612  gtid, target_gtid, (void *)NULL));
1613  __kmp_unlock_suspend_mx(th);
1614  return;
1615  } else if (flag->get_type() != th->th.th_sleep_loc_type) {
1616  // Flag type does not appear to match this function template; possibly the
1617  // thread is sleeping on something else. Try null resume again.
1618  KF_TRACE(
1619  5,
1620  ("__kmp_resume_template: T#%d retrying, thread T#%d Mismatch flag(%p), "
1621  "spin(%p) type=%d ptr_type=%d\n",
1622  gtid, target_gtid, flag, flag->get(), flag->get_type(),
1623  th->th.th_sleep_loc_type));
1624  __kmp_unlock_suspend_mx(th);
1625  __kmp_null_resume_wrapper(th);
1626  return;
1627  } else { // if multiple threads are sleeping, flag should be internally
1628  // referring to a specific thread here
1629  if (!flag->is_sleeping()) {
1630  KF_TRACE(5, ("__kmp_resume_template: T#%d exiting, thread T#%d already "
1631  "awake: flag(%p): %u\n",
1632  gtid, target_gtid, flag->get(), (unsigned int)flag->load()));
1633  __kmp_unlock_suspend_mx(th);
1634  return;
1635  }
1636  }
1637  KMP_DEBUG_ASSERT(flag);
1638  flag->unset_sleeping();
1639  TCW_PTR(th->th.th_sleep_loc, NULL);
1640  th->th.th_sleep_loc_type = flag_unset;
1641 
1642  KF_TRACE(5, ("__kmp_resume_template: T#%d about to wakeup T#%d, reset "
1643  "sleep bit for flag's loc(%p): %u\n",
1644  gtid, target_gtid, flag->get(), (unsigned int)flag->load()));
1645 
1646 #ifdef DEBUG_SUSPEND
1647  {
1648  char buffer[128];
1649  __kmp_print_cond(buffer, &th->th.th_suspend_cv);
1650  __kmp_printf("__kmp_resume_template: T#%d resuming T#%d: %s\n", gtid,
1651  target_gtid, buffer);
1652  }
1653 #endif
1654  status = pthread_cond_signal(&th->th.th_suspend_cv.c_cond);
1655  KMP_CHECK_SYSFAIL("pthread_cond_signal", status);
1656  __kmp_unlock_suspend_mx(th);
1657  KF_TRACE(30, ("__kmp_resume_template: T#%d exiting after signaling wake up"
1658  " for T#%d\n",
1659  gtid, target_gtid));
1660 }
1661 
1662 template <bool C, bool S>
1663 void __kmp_resume_32(int target_gtid, kmp_flag_32<C, S> *flag) {
1664  __kmp_resume_template(target_gtid, flag);
1665 }
1666 template <bool C, bool S>
1667 void __kmp_resume_64(int target_gtid, kmp_flag_64<C, S> *flag) {
1668  __kmp_resume_template(target_gtid, flag);
1669 }
1670 template <bool C, bool S>
1671 void __kmp_atomic_resume_64(int target_gtid, kmp_atomic_flag_64<C, S> *flag) {
1672  __kmp_resume_template(target_gtid, flag);
1673 }
1674 void __kmp_resume_oncore(int target_gtid, kmp_flag_oncore *flag) {
1675  __kmp_resume_template(target_gtid, flag);
1676 }
1677 
1678 template void __kmp_resume_32<false, true>(int, kmp_flag_32<false, true> *);
1679 template void __kmp_resume_32<false, false>(int, kmp_flag_32<false, false> *);
1680 template void __kmp_resume_64<false, true>(int, kmp_flag_64<false, true> *);
1681 template void
1682 __kmp_atomic_resume_64<false, true>(int, kmp_atomic_flag_64<false, true> *);
1683 
1684 #if KMP_USE_MONITOR
1685 void __kmp_resume_monitor() {
1686  KMP_TIME_DEVELOPER_PARTITIONED_BLOCK(USER_resume);
1687  int status;
1688 #ifdef KMP_DEBUG
1689  int gtid = TCR_4(__kmp_init_gtid) ? __kmp_get_gtid() : -1;
1690  KF_TRACE(30, ("__kmp_resume_monitor: T#%d wants to wakeup T#%d enter\n", gtid,
1691  KMP_GTID_MONITOR));
1692  KMP_DEBUG_ASSERT(gtid != KMP_GTID_MONITOR);
1693 #endif
1694  status = pthread_mutex_lock(&__kmp_wait_mx.m_mutex);
1695  KMP_CHECK_SYSFAIL("pthread_mutex_lock", status);
1696 #ifdef DEBUG_SUSPEND
1697  {
1698  char buffer[128];
1699  __kmp_print_cond(buffer, &__kmp_wait_cv.c_cond);
1700  __kmp_printf("__kmp_resume_monitor: T#%d resuming T#%d: %s\n", gtid,
1701  KMP_GTID_MONITOR, buffer);
1702  }
1703 #endif
1704  status = pthread_cond_signal(&__kmp_wait_cv.c_cond);
1705  KMP_CHECK_SYSFAIL("pthread_cond_signal", status);
1706  status = pthread_mutex_unlock(&__kmp_wait_mx.m_mutex);
1707  KMP_CHECK_SYSFAIL("pthread_mutex_unlock", status);
1708  KF_TRACE(30, ("__kmp_resume_monitor: T#%d exiting after signaling wake up"
1709  " for T#%d\n",
1710  gtid, KMP_GTID_MONITOR));
1711 }
1712 #endif // KMP_USE_MONITOR
1713 
1714 void __kmp_yield() { sched_yield(); }
1715 
1716 void __kmp_gtid_set_specific(int gtid) {
1717  if (__kmp_init_gtid) {
1718  int status;
1719  status = pthread_setspecific(__kmp_gtid_threadprivate_key,
1720  (void *)(intptr_t)(gtid + 1));
1721  KMP_CHECK_SYSFAIL("pthread_setspecific", status);
1722  } else {
1723  KA_TRACE(50, ("__kmp_gtid_set_specific: runtime shutdown, returning\n"));
1724  }
1725 }
1726 
1727 int __kmp_gtid_get_specific() {
1728  int gtid;
1729  if (!__kmp_init_gtid) {
1730  KA_TRACE(50, ("__kmp_gtid_get_specific: runtime shutdown, returning "
1731  "KMP_GTID_SHUTDOWN\n"));
1732  return KMP_GTID_SHUTDOWN;
1733  }
1734  gtid = (int)(size_t)pthread_getspecific(__kmp_gtid_threadprivate_key);
1735  if (gtid == 0) {
1736  gtid = KMP_GTID_DNE;
1737  } else {
1738  gtid--;
1739  }
1740  KA_TRACE(50, ("__kmp_gtid_get_specific: key:%d gtid:%d\n",
1741  __kmp_gtid_threadprivate_key, gtid));
1742  return gtid;
1743 }
1744 
1745 double __kmp_read_cpu_time(void) {
1746  /*clock_t t;*/
1747  struct tms buffer;
1748 
1749  /*t =*/times(&buffer);
1750 
1751  return (double)(buffer.tms_utime + buffer.tms_cutime) /
1752  (double)CLOCKS_PER_SEC;
1753 }
1754 
1755 int __kmp_read_system_info(struct kmp_sys_info *info) {
1756  int status;
1757  struct rusage r_usage;
1758 
1759  memset(info, 0, sizeof(*info));
1760 
1761  status = getrusage(RUSAGE_SELF, &r_usage);
1762  KMP_CHECK_SYSFAIL_ERRNO("getrusage", status);
1763 
1764  // The maximum resident set size utilized (in kilobytes)
1765  info->maxrss = r_usage.ru_maxrss;
1766  // The number of page faults serviced without any I/O
1767  info->minflt = r_usage.ru_minflt;
1768  // The number of page faults serviced that required I/O
1769  info->majflt = r_usage.ru_majflt;
1770  // The number of times a process was "swapped" out of memory
1771  info->nswap = r_usage.ru_nswap;
1772  // The number of times the file system had to perform input
1773  info->inblock = r_usage.ru_inblock;
1774  // The number of times the file system had to perform output
1775  info->oublock = r_usage.ru_oublock;
1776  // The number of times a context switch was voluntarily
1777  info->nvcsw = r_usage.ru_nvcsw;
1778  // The number of times a context switch was forced
1779  info->nivcsw = r_usage.ru_nivcsw;
1780 
1781  return (status != 0);
1782 }
1783 
1784 void __kmp_read_system_time(double *delta) {
1785  double t_ns;
1786  struct timeval tval;
1787  struct timespec stop;
1788  int status;
1789 
1790  status = gettimeofday(&tval, NULL);
1791  KMP_CHECK_SYSFAIL_ERRNO("gettimeofday", status);
1792  TIMEVAL_TO_TIMESPEC(&tval, &stop);
1793  t_ns = (double)(TS2NS(stop) - TS2NS(__kmp_sys_timer_data.start));
1794  *delta = (t_ns * 1e-9);
1795 }
1796 
1797 void __kmp_clear_system_time(void) {
1798  struct timeval tval;
1799  int status;
1800  status = gettimeofday(&tval, NULL);
1801  KMP_CHECK_SYSFAIL_ERRNO("gettimeofday", status);
1802  TIMEVAL_TO_TIMESPEC(&tval, &__kmp_sys_timer_data.start);
1803 }
1804 
1805 static int __kmp_get_xproc(void) {
1806 
1807  int r = 0;
1808 
1809 #if KMP_OS_LINUX
1810 
1811  __kmp_type_convert(sysconf(_SC_NPROCESSORS_CONF), &(r));
1812 
1813 #elif KMP_OS_DRAGONFLY || KMP_OS_FREEBSD || KMP_OS_NETBSD || KMP_OS_OPENBSD || \
1814  KMP_OS_HURD
1815 
1816  __kmp_type_convert(sysconf(_SC_NPROCESSORS_ONLN), &(r));
1817 
1818 #elif KMP_OS_DARWIN
1819 
1820  // Bug C77011 High "OpenMP Threads and number of active cores".
1821 
1822  // Find the number of available CPUs.
1823  kern_return_t rc;
1824  host_basic_info_data_t info;
1825  mach_msg_type_number_t num = HOST_BASIC_INFO_COUNT;
1826  rc = host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&info, &num);
1827  if (rc == 0 && num == HOST_BASIC_INFO_COUNT) {
1828  // Cannot use KA_TRACE() here because this code works before trace support
1829  // is initialized.
1830  r = info.avail_cpus;
1831  } else {
1832  KMP_WARNING(CantGetNumAvailCPU);
1833  KMP_INFORM(AssumedNumCPU);
1834  }
1835 
1836 #else
1837 
1838 #error "Unknown or unsupported OS."
1839 
1840 #endif
1841 
1842  return r > 0 ? r : 2; /* guess value of 2 if OS told us 0 */
1843 
1844 } // __kmp_get_xproc
1845 
1846 int __kmp_read_from_file(char const *path, char const *format, ...) {
1847  int result;
1848  va_list args;
1849 
1850  va_start(args, format);
1851  FILE *f = fopen(path, "rb");
1852  if (f == NULL) {
1853  va_end(args);
1854  return 0;
1855  }
1856  result = vfscanf(f, format, args);
1857  fclose(f);
1858  va_end(args);
1859 
1860  return result;
1861 }
1862 
1863 void __kmp_runtime_initialize(void) {
1864  int status;
1865  pthread_mutexattr_t mutex_attr;
1866  pthread_condattr_t cond_attr;
1867 
1868  if (__kmp_init_runtime) {
1869  return;
1870  }
1871 
1872 #if (KMP_ARCH_X86 || KMP_ARCH_X86_64)
1873  if (!__kmp_cpuinfo.initialized) {
1874  __kmp_query_cpuid(&__kmp_cpuinfo);
1875  }
1876 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
1877 
1878  __kmp_xproc = __kmp_get_xproc();
1879 
1880 #if !KMP_32_BIT_ARCH
1881  struct rlimit rlim;
1882  // read stack size of calling thread, save it as default for worker threads;
1883  // this should be done before reading environment variables
1884  status = getrlimit(RLIMIT_STACK, &rlim);
1885  if (status == 0) { // success?
1886  __kmp_stksize = rlim.rlim_cur;
1887  __kmp_check_stksize(&__kmp_stksize); // check value and adjust if needed
1888  }
1889 #endif /* KMP_32_BIT_ARCH */
1890 
1891  if (sysconf(_SC_THREADS)) {
1892 
1893  /* Query the maximum number of threads */
1894  __kmp_type_convert(sysconf(_SC_THREAD_THREADS_MAX), &(__kmp_sys_max_nth));
1895  if (__kmp_sys_max_nth == -1) {
1896  /* Unlimited threads for NPTL */
1897  __kmp_sys_max_nth = INT_MAX;
1898  } else if (__kmp_sys_max_nth <= 1) {
1899  /* Can't tell, just use PTHREAD_THREADS_MAX */
1900  __kmp_sys_max_nth = KMP_MAX_NTH;
1901  }
1902 
1903  /* Query the minimum stack size */
1904  __kmp_sys_min_stksize = sysconf(_SC_THREAD_STACK_MIN);
1905  if (__kmp_sys_min_stksize <= 1) {
1906  __kmp_sys_min_stksize = KMP_MIN_STKSIZE;
1907  }
1908  }
1909 
1910  /* Set up minimum number of threads to switch to TLS gtid */
1911  __kmp_tls_gtid_min = KMP_TLS_GTID_MIN;
1912 
1913  status = pthread_key_create(&__kmp_gtid_threadprivate_key,
1914  __kmp_internal_end_dest);
1915  KMP_CHECK_SYSFAIL("pthread_key_create", status);
1916  status = pthread_mutexattr_init(&mutex_attr);
1917  KMP_CHECK_SYSFAIL("pthread_mutexattr_init", status);
1918  status = pthread_mutex_init(&__kmp_wait_mx.m_mutex, &mutex_attr);
1919  KMP_CHECK_SYSFAIL("pthread_mutex_init", status);
1920  status = pthread_mutexattr_destroy(&mutex_attr);
1921  KMP_CHECK_SYSFAIL("pthread_mutexattr_destroy", status);
1922  status = pthread_condattr_init(&cond_attr);
1923  KMP_CHECK_SYSFAIL("pthread_condattr_init", status);
1924  status = pthread_cond_init(&__kmp_wait_cv.c_cond, &cond_attr);
1925  KMP_CHECK_SYSFAIL("pthread_cond_init", status);
1926  status = pthread_condattr_destroy(&cond_attr);
1927  KMP_CHECK_SYSFAIL("pthread_condattr_destroy", status);
1928 #if USE_ITT_BUILD
1929  __kmp_itt_initialize();
1930 #endif /* USE_ITT_BUILD */
1931 
1932  __kmp_init_runtime = TRUE;
1933 }
1934 
1935 void __kmp_runtime_destroy(void) {
1936  int status;
1937 
1938  if (!__kmp_init_runtime) {
1939  return; // Nothing to do.
1940  }
1941 
1942 #if USE_ITT_BUILD
1943  __kmp_itt_destroy();
1944 #endif /* USE_ITT_BUILD */
1945 
1946  status = pthread_key_delete(__kmp_gtid_threadprivate_key);
1947  KMP_CHECK_SYSFAIL("pthread_key_delete", status);
1948 
1949  status = pthread_mutex_destroy(&__kmp_wait_mx.m_mutex);
1950  if (status != 0 && status != EBUSY) {
1951  KMP_SYSFAIL("pthread_mutex_destroy", status);
1952  }
1953  status = pthread_cond_destroy(&__kmp_wait_cv.c_cond);
1954  if (status != 0 && status != EBUSY) {
1955  KMP_SYSFAIL("pthread_cond_destroy", status);
1956  }
1957 #if KMP_AFFINITY_SUPPORTED
1958  __kmp_affinity_uninitialize();
1959 #endif
1960 
1961  __kmp_init_runtime = FALSE;
1962 }
1963 
1964 /* Put the thread to sleep for a time period */
1965 /* NOTE: not currently used anywhere */
1966 void __kmp_thread_sleep(int millis) { sleep((millis + 500) / 1000); }
1967 
1968 /* Calculate the elapsed wall clock time for the user */
1969 void __kmp_elapsed(double *t) {
1970  int status;
1971 #ifdef FIX_SGI_CLOCK
1972  struct timespec ts;
1973 
1974  status = clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
1975  KMP_CHECK_SYSFAIL_ERRNO("clock_gettime", status);
1976  *t =
1977  (double)ts.tv_nsec * (1.0 / (double)KMP_NSEC_PER_SEC) + (double)ts.tv_sec;
1978 #else
1979  struct timeval tv;
1980 
1981  status = gettimeofday(&tv, NULL);
1982  KMP_CHECK_SYSFAIL_ERRNO("gettimeofday", status);
1983  *t =
1984  (double)tv.tv_usec * (1.0 / (double)KMP_USEC_PER_SEC) + (double)tv.tv_sec;
1985 #endif
1986 }
1987 
1988 /* Calculate the elapsed wall clock tick for the user */
1989 void __kmp_elapsed_tick(double *t) { *t = 1 / (double)CLOCKS_PER_SEC; }
1990 
1991 /* Return the current time stamp in nsec */
1992 kmp_uint64 __kmp_now_nsec() {
1993  struct timeval t;
1994  gettimeofday(&t, NULL);
1995  kmp_uint64 nsec = (kmp_uint64)KMP_NSEC_PER_SEC * (kmp_uint64)t.tv_sec +
1996  (kmp_uint64)1000 * (kmp_uint64)t.tv_usec;
1997  return nsec;
1998 }
1999 
2000 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
2001 /* Measure clock ticks per millisecond */
2002 void __kmp_initialize_system_tick() {
2003  kmp_uint64 now, nsec2, diff;
2004  kmp_uint64 delay = 100000; // 50~100 usec on most machines.
2005  kmp_uint64 nsec = __kmp_now_nsec();
2006  kmp_uint64 goal = __kmp_hardware_timestamp() + delay;
2007  while ((now = __kmp_hardware_timestamp()) < goal)
2008  ;
2009  nsec2 = __kmp_now_nsec();
2010  diff = nsec2 - nsec;
2011  if (diff > 0) {
2012  kmp_uint64 tpms = ((kmp_uint64)1e6 * (delay + (now - goal)) / diff);
2013  if (tpms > 0)
2014  __kmp_ticks_per_msec = tpms;
2015  }
2016 }
2017 #endif
2018 
2019 /* Determine whether the given address is mapped into the current address
2020  space. */
2021 
2022 int __kmp_is_address_mapped(void *addr) {
2023 
2024  int found = 0;
2025  int rc;
2026 
2027 #if KMP_OS_LINUX || KMP_OS_HURD
2028 
2029  /* On GNUish OSes, read the /proc/<pid>/maps pseudo-file to get all the
2030  address ranges mapped into the address space. */
2031 
2032  char *name = __kmp_str_format("/proc/%d/maps", getpid());
2033  FILE *file = NULL;
2034 
2035  file = fopen(name, "r");
2036  KMP_ASSERT(file != NULL);
2037 
2038  for (;;) {
2039 
2040  void *beginning = NULL;
2041  void *ending = NULL;
2042  char perms[5];
2043 
2044  rc = fscanf(file, "%p-%p %4s %*[^\n]\n", &beginning, &ending, perms);
2045  if (rc == EOF) {
2046  break;
2047  }
2048  KMP_ASSERT(rc == 3 &&
2049  KMP_STRLEN(perms) == 4); // Make sure all fields are read.
2050 
2051  // Ending address is not included in the region, but beginning is.
2052  if ((addr >= beginning) && (addr < ending)) {
2053  perms[2] = 0; // 3th and 4th character does not matter.
2054  if (strcmp(perms, "rw") == 0) {
2055  // Memory we are looking for should be readable and writable.
2056  found = 1;
2057  }
2058  break;
2059  }
2060  }
2061 
2062  // Free resources.
2063  fclose(file);
2064  KMP_INTERNAL_FREE(name);
2065 #elif KMP_OS_FREEBSD
2066  char *buf;
2067  size_t lstsz;
2068  int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_VMMAP, getpid()};
2069  rc = sysctl(mib, 4, NULL, &lstsz, NULL, 0);
2070  if (rc < 0)
2071  return 0;
2072  // We pass from number of vm entry's semantic
2073  // to size of whole entry map list.
2074  lstsz = lstsz * 4 / 3;
2075  buf = reinterpret_cast<char *>(kmpc_malloc(lstsz));
2076  rc = sysctl(mib, 4, buf, &lstsz, NULL, 0);
2077  if (rc < 0) {
2078  kmpc_free(buf);
2079  return 0;
2080  }
2081 
2082  char *lw = buf;
2083  char *up = buf + lstsz;
2084 
2085  while (lw < up) {
2086  struct kinfo_vmentry *cur = reinterpret_cast<struct kinfo_vmentry *>(lw);
2087  size_t cursz = cur->kve_structsize;
2088  if (cursz == 0)
2089  break;
2090  void *start = reinterpret_cast<void *>(cur->kve_start);
2091  void *end = reinterpret_cast<void *>(cur->kve_end);
2092  // Readable/Writable addresses within current map entry
2093  if ((addr >= start) && (addr < end)) {
2094  if ((cur->kve_protection & KVME_PROT_READ) != 0 &&
2095  (cur->kve_protection & KVME_PROT_WRITE) != 0) {
2096  found = 1;
2097  break;
2098  }
2099  }
2100  lw += cursz;
2101  }
2102  kmpc_free(buf);
2103 
2104 #elif KMP_OS_DARWIN
2105 
2106  /* On OS X*, /proc pseudo filesystem is not available. Try to read memory
2107  using vm interface. */
2108 
2109  int buffer;
2110  vm_size_t count;
2111  rc = vm_read_overwrite(
2112  mach_task_self(), // Task to read memory of.
2113  (vm_address_t)(addr), // Address to read from.
2114  1, // Number of bytes to be read.
2115  (vm_address_t)(&buffer), // Address of buffer to save read bytes in.
2116  &count // Address of var to save number of read bytes in.
2117  );
2118  if (rc == 0) {
2119  // Memory successfully read.
2120  found = 1;
2121  }
2122 
2123 #elif KMP_OS_NETBSD
2124 
2125  int mib[5];
2126  mib[0] = CTL_VM;
2127  mib[1] = VM_PROC;
2128  mib[2] = VM_PROC_MAP;
2129  mib[3] = getpid();
2130  mib[4] = sizeof(struct kinfo_vmentry);
2131 
2132  size_t size;
2133  rc = sysctl(mib, __arraycount(mib), NULL, &size, NULL, 0);
2134  KMP_ASSERT(!rc);
2135  KMP_ASSERT(size);
2136 
2137  size = size * 4 / 3;
2138  struct kinfo_vmentry *kiv = (struct kinfo_vmentry *)KMP_INTERNAL_MALLOC(size);
2139  KMP_ASSERT(kiv);
2140 
2141  rc = sysctl(mib, __arraycount(mib), kiv, &size, NULL, 0);
2142  KMP_ASSERT(!rc);
2143  KMP_ASSERT(size);
2144 
2145  for (size_t i = 0; i < size; i++) {
2146  if (kiv[i].kve_start >= (uint64_t)addr &&
2147  kiv[i].kve_end <= (uint64_t)addr) {
2148  found = 1;
2149  break;
2150  }
2151  }
2152  KMP_INTERNAL_FREE(kiv);
2153 #elif KMP_OS_OPENBSD
2154 
2155  int mib[3];
2156  mib[0] = CTL_KERN;
2157  mib[1] = KERN_PROC_VMMAP;
2158  mib[2] = getpid();
2159 
2160  size_t size;
2161  uint64_t end;
2162  rc = sysctl(mib, 3, NULL, &size, NULL, 0);
2163  KMP_ASSERT(!rc);
2164  KMP_ASSERT(size);
2165  end = size;
2166 
2167  struct kinfo_vmentry kiv = {.kve_start = 0};
2168 
2169  while ((rc = sysctl(mib, 3, &kiv, &size, NULL, 0)) == 0) {
2170  KMP_ASSERT(size);
2171  if (kiv.kve_end == end)
2172  break;
2173 
2174  if (kiv.kve_start >= (uint64_t)addr && kiv.kve_end <= (uint64_t)addr) {
2175  found = 1;
2176  break;
2177  }
2178  kiv.kve_start += 1;
2179  }
2180 #elif KMP_OS_DRAGONFLY
2181 
2182  // FIXME(DragonFly): Implement this
2183  found = 1;
2184 
2185 #else
2186 
2187 #error "Unknown or unsupported OS"
2188 
2189 #endif
2190 
2191  return found;
2192 
2193 } // __kmp_is_address_mapped
2194 
2195 #ifdef USE_LOAD_BALANCE
2196 
2197 #if KMP_OS_DARWIN || KMP_OS_NETBSD
2198 
2199 // The function returns the rounded value of the system load average
2200 // during given time interval which depends on the value of
2201 // __kmp_load_balance_interval variable (default is 60 sec, other values
2202 // may be 300 sec or 900 sec).
2203 // It returns -1 in case of error.
2204 int __kmp_get_load_balance(int max) {
2205  double averages[3];
2206  int ret_avg = 0;
2207 
2208  int res = getloadavg(averages, 3);
2209 
2210  // Check __kmp_load_balance_interval to determine which of averages to use.
2211  // getloadavg() may return the number of samples less than requested that is
2212  // less than 3.
2213  if (__kmp_load_balance_interval < 180 && (res >= 1)) {
2214  ret_avg = (int)averages[0]; // 1 min
2215  } else if ((__kmp_load_balance_interval >= 180 &&
2216  __kmp_load_balance_interval < 600) &&
2217  (res >= 2)) {
2218  ret_avg = (int)averages[1]; // 5 min
2219  } else if ((__kmp_load_balance_interval >= 600) && (res == 3)) {
2220  ret_avg = (int)averages[2]; // 15 min
2221  } else { // Error occurred
2222  return -1;
2223  }
2224 
2225  return ret_avg;
2226 }
2227 
2228 #else // Linux* OS
2229 
2230 // The function returns number of running (not sleeping) threads, or -1 in case
2231 // of error. Error could be reported if Linux* OS kernel too old (without
2232 // "/proc" support). Counting running threads stops if max running threads
2233 // encountered.
2234 int __kmp_get_load_balance(int max) {
2235  static int permanent_error = 0;
2236  static int glb_running_threads = 0; // Saved count of the running threads for
2237  // the thread balance algorithm
2238  static double glb_call_time = 0; /* Thread balance algorithm call time */
2239 
2240  int running_threads = 0; // Number of running threads in the system.
2241 
2242  DIR *proc_dir = NULL; // Handle of "/proc/" directory.
2243  struct dirent *proc_entry = NULL;
2244 
2245  kmp_str_buf_t task_path; // "/proc/<pid>/task/<tid>/" path.
2246  DIR *task_dir = NULL; // Handle of "/proc/<pid>/task/<tid>/" directory.
2247  struct dirent *task_entry = NULL;
2248  int task_path_fixed_len;
2249 
2250  kmp_str_buf_t stat_path; // "/proc/<pid>/task/<tid>/stat" path.
2251  int stat_file = -1;
2252  int stat_path_fixed_len;
2253 
2254 #ifdef KMP_DEBUG
2255  int total_processes = 0; // Total number of processes in system.
2256 #endif
2257 
2258  double call_time = 0.0;
2259 
2260  __kmp_str_buf_init(&task_path);
2261  __kmp_str_buf_init(&stat_path);
2262 
2263  __kmp_elapsed(&call_time);
2264 
2265  if (glb_call_time &&
2266  (call_time - glb_call_time < __kmp_load_balance_interval)) {
2267  running_threads = glb_running_threads;
2268  goto finish;
2269  }
2270 
2271  glb_call_time = call_time;
2272 
2273  // Do not spend time on scanning "/proc/" if we have a permanent error.
2274  if (permanent_error) {
2275  running_threads = -1;
2276  goto finish;
2277  }
2278 
2279  if (max <= 0) {
2280  max = INT_MAX;
2281  }
2282 
2283  // Open "/proc/" directory.
2284  proc_dir = opendir("/proc");
2285  if (proc_dir == NULL) {
2286  // Cannot open "/prroc/". Probably the kernel does not support it. Return an
2287  // error now and in subsequent calls.
2288  running_threads = -1;
2289  permanent_error = 1;
2290  goto finish;
2291  }
2292 
2293  // Initialize fixed part of task_path. This part will not change.
2294  __kmp_str_buf_cat(&task_path, "/proc/", 6);
2295  task_path_fixed_len = task_path.used; // Remember number of used characters.
2296 
2297  proc_entry = readdir(proc_dir);
2298  while (proc_entry != NULL) {
2299  // Proc entry is a directory and name starts with a digit. Assume it is a
2300  // process' directory.
2301  if (proc_entry->d_type == DT_DIR && isdigit(proc_entry->d_name[0])) {
2302 
2303 #ifdef KMP_DEBUG
2304  ++total_processes;
2305 #endif
2306  // Make sure init process is the very first in "/proc", so we can replace
2307  // strcmp( proc_entry->d_name, "1" ) == 0 with simpler total_processes ==
2308  // 1. We are going to check that total_processes == 1 => d_name == "1" is
2309  // true (where "=>" is implication). Since C++ does not have => operator,
2310  // let us replace it with its equivalent: a => b == ! a || b.
2311  KMP_DEBUG_ASSERT(total_processes != 1 ||
2312  strcmp(proc_entry->d_name, "1") == 0);
2313 
2314  // Construct task_path.
2315  task_path.used = task_path_fixed_len; // Reset task_path to "/proc/".
2316  __kmp_str_buf_cat(&task_path, proc_entry->d_name,
2317  KMP_STRLEN(proc_entry->d_name));
2318  __kmp_str_buf_cat(&task_path, "/task", 5);
2319 
2320  task_dir = opendir(task_path.str);
2321  if (task_dir == NULL) {
2322  // Process can finish between reading "/proc/" directory entry and
2323  // opening process' "task/" directory. So, in general case we should not
2324  // complain, but have to skip this process and read the next one. But on
2325  // systems with no "task/" support we will spend lot of time to scan
2326  // "/proc/" tree again and again without any benefit. "init" process
2327  // (its pid is 1) should exist always, so, if we cannot open
2328  // "/proc/1/task/" directory, it means "task/" is not supported by
2329  // kernel. Report an error now and in the future.
2330  if (strcmp(proc_entry->d_name, "1") == 0) {
2331  running_threads = -1;
2332  permanent_error = 1;
2333  goto finish;
2334  }
2335  } else {
2336  // Construct fixed part of stat file path.
2337  __kmp_str_buf_clear(&stat_path);
2338  __kmp_str_buf_cat(&stat_path, task_path.str, task_path.used);
2339  __kmp_str_buf_cat(&stat_path, "/", 1);
2340  stat_path_fixed_len = stat_path.used;
2341 
2342  task_entry = readdir(task_dir);
2343  while (task_entry != NULL) {
2344  // It is a directory and name starts with a digit.
2345  if (proc_entry->d_type == DT_DIR && isdigit(task_entry->d_name[0])) {
2346 
2347  // Construct complete stat file path. Easiest way would be:
2348  // __kmp_str_buf_print( & stat_path, "%s/%s/stat", task_path.str,
2349  // task_entry->d_name );
2350  // but seriae of __kmp_str_buf_cat works a bit faster.
2351  stat_path.used =
2352  stat_path_fixed_len; // Reset stat path to its fixed part.
2353  __kmp_str_buf_cat(&stat_path, task_entry->d_name,
2354  KMP_STRLEN(task_entry->d_name));
2355  __kmp_str_buf_cat(&stat_path, "/stat", 5);
2356 
2357  // Note: Low-level API (open/read/close) is used. High-level API
2358  // (fopen/fclose) works ~ 30 % slower.
2359  stat_file = open(stat_path.str, O_RDONLY);
2360  if (stat_file == -1) {
2361  // We cannot report an error because task (thread) can terminate
2362  // just before reading this file.
2363  } else {
2364  /* Content of "stat" file looks like:
2365  24285 (program) S ...
2366 
2367  It is a single line (if program name does not include funny
2368  symbols). First number is a thread id, then name of executable
2369  file name in paretheses, then state of the thread. We need just
2370  thread state.
2371 
2372  Good news: Length of program name is 15 characters max. Longer
2373  names are truncated.
2374 
2375  Thus, we need rather short buffer: 15 chars for program name +
2376  2 parenthesis, + 3 spaces + ~7 digits of pid = 37.
2377 
2378  Bad news: Program name may contain special symbols like space,
2379  closing parenthesis, or even new line. This makes parsing
2380  "stat" file not 100 % reliable. In case of fanny program names
2381  parsing may fail (report incorrect thread state).
2382 
2383  Parsing "status" file looks more promissing (due to different
2384  file structure and escaping special symbols) but reading and
2385  parsing of "status" file works slower.
2386  -- ln
2387  */
2388  char buffer[65];
2389  ssize_t len;
2390  len = read(stat_file, buffer, sizeof(buffer) - 1);
2391  if (len >= 0) {
2392  buffer[len] = 0;
2393  // Using scanf:
2394  // sscanf( buffer, "%*d (%*s) %c ", & state );
2395  // looks very nice, but searching for a closing parenthesis
2396  // works a bit faster.
2397  char *close_parent = strstr(buffer, ") ");
2398  if (close_parent != NULL) {
2399  char state = *(close_parent + 2);
2400  if (state == 'R') {
2401  ++running_threads;
2402  if (running_threads >= max) {
2403  goto finish;
2404  }
2405  }
2406  }
2407  }
2408  close(stat_file);
2409  stat_file = -1;
2410  }
2411  }
2412  task_entry = readdir(task_dir);
2413  }
2414  closedir(task_dir);
2415  task_dir = NULL;
2416  }
2417  }
2418  proc_entry = readdir(proc_dir);
2419  }
2420 
2421  // There _might_ be a timing hole where the thread executing this
2422  // code get skipped in the load balance, and running_threads is 0.
2423  // Assert in the debug builds only!!!
2424  KMP_DEBUG_ASSERT(running_threads > 0);
2425  if (running_threads <= 0) {
2426  running_threads = 1;
2427  }
2428 
2429 finish: // Clean up and exit.
2430  if (proc_dir != NULL) {
2431  closedir(proc_dir);
2432  }
2433  __kmp_str_buf_free(&task_path);
2434  if (task_dir != NULL) {
2435  closedir(task_dir);
2436  }
2437  __kmp_str_buf_free(&stat_path);
2438  if (stat_file != -1) {
2439  close(stat_file);
2440  }
2441 
2442  glb_running_threads = running_threads;
2443 
2444  return running_threads;
2445 
2446 } // __kmp_get_load_balance
2447 
2448 #endif // KMP_OS_DARWIN
2449 
2450 #endif // USE_LOAD_BALANCE
2451 
2452 #if !(KMP_ARCH_X86 || KMP_ARCH_X86_64 || KMP_MIC || \
2453  ((KMP_OS_LINUX || KMP_OS_DARWIN) && KMP_ARCH_AARCH64) || \
2454  KMP_ARCH_PPC64 || KMP_ARCH_RISCV64 || KMP_ARCH_LOONGARCH64 || \
2455  KMP_ARCH_ARM)
2456 
2457 // we really only need the case with 1 argument, because CLANG always build
2458 // a struct of pointers to shared variables referenced in the outlined function
2459 int __kmp_invoke_microtask(microtask_t pkfn, int gtid, int tid, int argc,
2460  void *p_argv[]
2461 #if OMPT_SUPPORT
2462  ,
2463  void **exit_frame_ptr
2464 #endif
2465 ) {
2466 #if OMPT_SUPPORT
2467  *exit_frame_ptr = OMPT_GET_FRAME_ADDRESS(0);
2468 #endif
2469 
2470  switch (argc) {
2471  default:
2472  fprintf(stderr, "Too many args to microtask: %d!\n", argc);
2473  fflush(stderr);
2474  exit(-1);
2475  case 0:
2476  (*pkfn)(&gtid, &tid);
2477  break;
2478  case 1:
2479  (*pkfn)(&gtid, &tid, p_argv[0]);
2480  break;
2481  case 2:
2482  (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1]);
2483  break;
2484  case 3:
2485  (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2]);
2486  break;
2487  case 4:
2488  (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3]);
2489  break;
2490  case 5:
2491  (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4]);
2492  break;
2493  case 6:
2494  (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2495  p_argv[5]);
2496  break;
2497  case 7:
2498  (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2499  p_argv[5], p_argv[6]);
2500  break;
2501  case 8:
2502  (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2503  p_argv[5], p_argv[6], p_argv[7]);
2504  break;
2505  case 9:
2506  (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2507  p_argv[5], p_argv[6], p_argv[7], p_argv[8]);
2508  break;
2509  case 10:
2510  (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2511  p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9]);
2512  break;
2513  case 11:
2514  (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2515  p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9], p_argv[10]);
2516  break;
2517  case 12:
2518  (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2519  p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9], p_argv[10],
2520  p_argv[11]);
2521  break;
2522  case 13:
2523  (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2524  p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9], p_argv[10],
2525  p_argv[11], p_argv[12]);
2526  break;
2527  case 14:
2528  (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2529  p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9], p_argv[10],
2530  p_argv[11], p_argv[12], p_argv[13]);
2531  break;
2532  case 15:
2533  (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2534  p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9], p_argv[10],
2535  p_argv[11], p_argv[12], p_argv[13], p_argv[14]);
2536  break;
2537  }
2538 
2539  return 1;
2540 }
2541 
2542 #endif
2543 
2544 #if KMP_OS_LINUX
2545 // Functions for hidden helper task
2546 namespace {
2547 // Condition variable for initializing hidden helper team
2548 pthread_cond_t hidden_helper_threads_initz_cond_var;
2549 pthread_mutex_t hidden_helper_threads_initz_lock;
2550 volatile int hidden_helper_initz_signaled = FALSE;
2551 
2552 // Condition variable for deinitializing hidden helper team
2553 pthread_cond_t hidden_helper_threads_deinitz_cond_var;
2554 pthread_mutex_t hidden_helper_threads_deinitz_lock;
2555 volatile int hidden_helper_deinitz_signaled = FALSE;
2556 
2557 // Condition variable for the wrapper function of main thread
2558 pthread_cond_t hidden_helper_main_thread_cond_var;
2559 pthread_mutex_t hidden_helper_main_thread_lock;
2560 volatile int hidden_helper_main_thread_signaled = FALSE;
2561 
2562 // Semaphore for worker threads. We don't use condition variable here in case
2563 // that when multiple signals are sent at the same time, only one thread might
2564 // be waken.
2565 sem_t hidden_helper_task_sem;
2566 } // namespace
2567 
2568 void __kmp_hidden_helper_worker_thread_wait() {
2569  int status = sem_wait(&hidden_helper_task_sem);
2570  KMP_CHECK_SYSFAIL("sem_wait", status);
2571 }
2572 
2573 void __kmp_do_initialize_hidden_helper_threads() {
2574  // Initialize condition variable
2575  int status =
2576  pthread_cond_init(&hidden_helper_threads_initz_cond_var, nullptr);
2577  KMP_CHECK_SYSFAIL("pthread_cond_init", status);
2578 
2579  status = pthread_cond_init(&hidden_helper_threads_deinitz_cond_var, nullptr);
2580  KMP_CHECK_SYSFAIL("pthread_cond_init", status);
2581 
2582  status = pthread_cond_init(&hidden_helper_main_thread_cond_var, nullptr);
2583  KMP_CHECK_SYSFAIL("pthread_cond_init", status);
2584 
2585  status = pthread_mutex_init(&hidden_helper_threads_initz_lock, nullptr);
2586  KMP_CHECK_SYSFAIL("pthread_mutex_init", status);
2587 
2588  status = pthread_mutex_init(&hidden_helper_threads_deinitz_lock, nullptr);
2589  KMP_CHECK_SYSFAIL("pthread_mutex_init", status);
2590 
2591  status = pthread_mutex_init(&hidden_helper_main_thread_lock, nullptr);
2592  KMP_CHECK_SYSFAIL("pthread_mutex_init", status);
2593 
2594  // Initialize the semaphore
2595  status = sem_init(&hidden_helper_task_sem, 0, 0);
2596  KMP_CHECK_SYSFAIL("sem_init", status);
2597 
2598  // Create a new thread to finish initialization
2599  pthread_t handle;
2600  status = pthread_create(
2601  &handle, nullptr,
2602  [](void *) -> void * {
2603  __kmp_hidden_helper_threads_initz_routine();
2604  return nullptr;
2605  },
2606  nullptr);
2607  KMP_CHECK_SYSFAIL("pthread_create", status);
2608 }
2609 
2610 void __kmp_hidden_helper_threads_initz_wait() {
2611  // Initial thread waits here for the completion of the initialization. The
2612  // condition variable will be notified by main thread of hidden helper teams.
2613  int status = pthread_mutex_lock(&hidden_helper_threads_initz_lock);
2614  KMP_CHECK_SYSFAIL("pthread_mutex_lock", status);
2615 
2616  if (!TCR_4(hidden_helper_initz_signaled)) {
2617  status = pthread_cond_wait(&hidden_helper_threads_initz_cond_var,
2618  &hidden_helper_threads_initz_lock);
2619  KMP_CHECK_SYSFAIL("pthread_cond_wait", status);
2620  }
2621 
2622  status = pthread_mutex_unlock(&hidden_helper_threads_initz_lock);
2623  KMP_CHECK_SYSFAIL("pthread_mutex_unlock", status);
2624 }
2625 
2626 void __kmp_hidden_helper_initz_release() {
2627  // After all initialization, reset __kmp_init_hidden_helper_threads to false.
2628  int status = pthread_mutex_lock(&hidden_helper_threads_initz_lock);
2629  KMP_CHECK_SYSFAIL("pthread_mutex_lock", status);
2630 
2631  status = pthread_cond_signal(&hidden_helper_threads_initz_cond_var);
2632  KMP_CHECK_SYSFAIL("pthread_cond_wait", status);
2633 
2634  TCW_SYNC_4(hidden_helper_initz_signaled, TRUE);
2635 
2636  status = pthread_mutex_unlock(&hidden_helper_threads_initz_lock);
2637  KMP_CHECK_SYSFAIL("pthread_mutex_unlock", status);
2638 }
2639 
2640 void __kmp_hidden_helper_main_thread_wait() {
2641  // The main thread of hidden helper team will be blocked here. The
2642  // condition variable can only be signal in the destructor of RTL.
2643  int status = pthread_mutex_lock(&hidden_helper_main_thread_lock);
2644  KMP_CHECK_SYSFAIL("pthread_mutex_lock", status);
2645 
2646  if (!TCR_4(hidden_helper_main_thread_signaled)) {
2647  status = pthread_cond_wait(&hidden_helper_main_thread_cond_var,
2648  &hidden_helper_main_thread_lock);
2649  KMP_CHECK_SYSFAIL("pthread_cond_wait", status);
2650  }
2651 
2652  status = pthread_mutex_unlock(&hidden_helper_main_thread_lock);
2653  KMP_CHECK_SYSFAIL("pthread_mutex_unlock", status);
2654 }
2655 
2656 void __kmp_hidden_helper_main_thread_release() {
2657  // The initial thread of OpenMP RTL should call this function to wake up the
2658  // main thread of hidden helper team.
2659  int status = pthread_mutex_lock(&hidden_helper_main_thread_lock);
2660  KMP_CHECK_SYSFAIL("pthread_mutex_lock", status);
2661 
2662  status = pthread_cond_signal(&hidden_helper_main_thread_cond_var);
2663  KMP_CHECK_SYSFAIL("pthread_cond_signal", status);
2664 
2665  // The hidden helper team is done here
2666  TCW_SYNC_4(hidden_helper_main_thread_signaled, TRUE);
2667 
2668  status = pthread_mutex_unlock(&hidden_helper_main_thread_lock);
2669  KMP_CHECK_SYSFAIL("pthread_mutex_unlock", status);
2670 }
2671 
2672 void __kmp_hidden_helper_worker_thread_signal() {
2673  int status = sem_post(&hidden_helper_task_sem);
2674  KMP_CHECK_SYSFAIL("sem_post", status);
2675 }
2676 
2677 void __kmp_hidden_helper_threads_deinitz_wait() {
2678  // Initial thread waits here for the completion of the deinitialization. The
2679  // condition variable will be notified by main thread of hidden helper teams.
2680  int status = pthread_mutex_lock(&hidden_helper_threads_deinitz_lock);
2681  KMP_CHECK_SYSFAIL("pthread_mutex_lock", status);
2682 
2683  if (!TCR_4(hidden_helper_deinitz_signaled)) {
2684  status = pthread_cond_wait(&hidden_helper_threads_deinitz_cond_var,
2685  &hidden_helper_threads_deinitz_lock);
2686  KMP_CHECK_SYSFAIL("pthread_cond_wait", status);
2687  }
2688 
2689  status = pthread_mutex_unlock(&hidden_helper_threads_deinitz_lock);
2690  KMP_CHECK_SYSFAIL("pthread_mutex_unlock", status);
2691 }
2692 
2693 void __kmp_hidden_helper_threads_deinitz_release() {
2694  int status = pthread_mutex_lock(&hidden_helper_threads_deinitz_lock);
2695  KMP_CHECK_SYSFAIL("pthread_mutex_lock", status);
2696 
2697  status = pthread_cond_signal(&hidden_helper_threads_deinitz_cond_var);
2698  KMP_CHECK_SYSFAIL("pthread_cond_wait", status);
2699 
2700  TCW_SYNC_4(hidden_helper_deinitz_signaled, TRUE);
2701 
2702  status = pthread_mutex_unlock(&hidden_helper_threads_deinitz_lock);
2703  KMP_CHECK_SYSFAIL("pthread_mutex_unlock", status);
2704 }
2705 #else // KMP_OS_LINUX
2706 void __kmp_hidden_helper_worker_thread_wait() {
2707  KMP_ASSERT(0 && "Hidden helper task is not supported on this OS");
2708 }
2709 
2710 void __kmp_do_initialize_hidden_helper_threads() {
2711  KMP_ASSERT(0 && "Hidden helper task is not supported on this OS");
2712 }
2713 
2714 void __kmp_hidden_helper_threads_initz_wait() {
2715  KMP_ASSERT(0 && "Hidden helper task is not supported on this OS");
2716 }
2717 
2718 void __kmp_hidden_helper_initz_release() {
2719  KMP_ASSERT(0 && "Hidden helper task is not supported on this OS");
2720 }
2721 
2722 void __kmp_hidden_helper_main_thread_wait() {
2723  KMP_ASSERT(0 && "Hidden helper task is not supported on this OS");
2724 }
2725 
2726 void __kmp_hidden_helper_main_thread_release() {
2727  KMP_ASSERT(0 && "Hidden helper task is not supported on this OS");
2728 }
2729 
2730 void __kmp_hidden_helper_worker_thread_signal() {
2731  KMP_ASSERT(0 && "Hidden helper task is not supported on this OS");
2732 }
2733 
2734 void __kmp_hidden_helper_threads_deinitz_wait() {
2735  KMP_ASSERT(0 && "Hidden helper task is not supported on this OS");
2736 }
2737 
2738 void __kmp_hidden_helper_threads_deinitz_release() {
2739  KMP_ASSERT(0 && "Hidden helper task is not supported on this OS");
2740 }
2741 #endif // KMP_OS_LINUX
2742 
2743 // end of file //
#define KMP_INIT_PARTITIONED_TIMERS(name)
Initializes the partitioned timers to begin with name.
Definition: kmp_stats.h:940