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