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