blob: 871be6283c294874ca09e11778ee03a0e6211832 [file] [log] [blame]
Jim Cownie5e8470a2013-09-27 10:38:44 +00001/*
Jonathan Peytonde4749b2016-12-14 23:01:24 +00002 * z_Linux_util.cpp -- platform specific routines.
Jim Cownie5e8470a2013-09-27 10:38:44 +00003 */
4
Jim Cownie5e8470a2013-09-27 10:38:44 +00005//===----------------------------------------------------------------------===//
6//
Chandler Carruth57b08b02019-01-19 10:56:40 +00007// 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
Jim Cownie5e8470a2013-09-27 10:38:44 +000010//
11//===----------------------------------------------------------------------===//
12
Jim Cownie5e8470a2013-09-27 10:38:44 +000013#include "kmp.h"
Jonathan Peyton1cdd87a2016-11-14 21:08:35 +000014#include "kmp_affinity.h"
Jonathan Peyton30419822017-05-12 18:01:32 +000015#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"
Jim Cownie5e8470a2013-09-27 10:38:44 +000023
Kamil Rytarowski7e1ea992018-12-09 16:46:48 +000024#if !KMP_OS_DRAGONFLY && !KMP_OS_FREEBSD && !KMP_OS_NETBSD && !KMP_OS_OPENBSD
Jonathan Peyton30419822017-05-12 18:01:32 +000025#include <alloca.h>
Alp Toker763b9392014-02-28 09:42:41 +000026#endif
Jonathan Peyton30419822017-05-12 18:01:32 +000027#include <math.h> // HUGE_VAL.
Jim Cownie5e8470a2013-09-27 10:38:44 +000028#include <sys/resource.h>
29#include <sys/syscall.h>
Jonathan Peyton30419822017-05-12 18:01:32 +000030#include <sys/time.h>
31#include <sys/times.h>
32#include <unistd.h>
Jim Cownie5e8470a2013-09-27 10:38:44 +000033
Jim Cownie3051f972014-08-07 10:12:54 +000034#if KMP_OS_LINUX && !KMP_OS_CNK
Jonathan Peyton30419822017-05-12 18:01:32 +000035#include <sys/sysinfo.h>
36#if KMP_USE_FUTEX
37// We should really include <futex.h>, but that causes compatibility problems on
38// different Linux* OS distributions that either require that you include (or
39// break when you try to include) <pci/types.h>. Since all we need is the two
40// macros below (which are part of the kernel ABI, so can't change) we just
41// define the constants here and don't include <futex.h>
42#ifndef FUTEX_WAIT
43#define FUTEX_WAIT 0
44#endif
45#ifndef FUTEX_WAKE
46#define FUTEX_WAKE 1
47#endif
48#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +000049#elif KMP_OS_DARWIN
Jonathan Peyton30419822017-05-12 18:01:32 +000050#include <mach/mach.h>
51#include <sys/sysctl.h>
Kamil Rytarowskia56ac942018-12-09 16:40:33 +000052#elif KMP_OS_DRAGONFLY || KMP_OS_FREEBSD
David Carlierfef62e12019-09-28 19:01:59 +000053#include <sys/types.h>
54#include <sys/sysctl.h>
55#include <sys/user.h>
Jonathan Peyton30419822017-05-12 18:01:32 +000056#include <pthread_np.h>
Kamil Rytarowski316f4232018-12-11 18:35:07 +000057#elif KMP_OS_NETBSD
58#include <sys/types.h>
59#include <sys/sysctl.h>
Jim Cownie5e8470a2013-09-27 10:38:44 +000060#endif
61
Jim Cownie5e8470a2013-09-27 10:38:44 +000062#include <ctype.h>
Jonathan Peyton30419822017-05-12 18:01:32 +000063#include <dirent.h>
Jim Cownie5e8470a2013-09-27 10:38:44 +000064#include <fcntl.h>
65
Jonas Hahnfeld50fed042016-11-07 15:58:36 +000066#include "tsan_annotations.h"
67
Jim Cownie5e8470a2013-09-27 10:38:44 +000068struct kmp_sys_timer {
Jonathan Peyton30419822017-05-12 18:01:32 +000069 struct timespec start;
Jim Cownie5e8470a2013-09-27 10:38:44 +000070};
71
72// Convert timespec to nanoseconds.
73#define TS2NS(timespec) (((timespec).tv_sec * 1e9) + (timespec).tv_nsec)
74
75static struct kmp_sys_timer __kmp_sys_timer_data;
76
77#if KMP_HANDLE_SIGNALS
Jonathan Peyton30419822017-05-12 18:01:32 +000078typedef void (*sig_func_t)(int);
79STATIC_EFI2_WORKAROUND struct sigaction __kmp_sighldrs[NSIG];
80static sigset_t __kmp_sigset;
Jim Cownie5e8470a2013-09-27 10:38:44 +000081#endif
82
Jonathan Peyton30419822017-05-12 18:01:32 +000083static int __kmp_init_runtime = FALSE;
Jim Cownie5e8470a2013-09-27 10:38:44 +000084
85static int __kmp_fork_count = 0;
86
Jonathan Peyton30419822017-05-12 18:01:32 +000087static pthread_condattr_t __kmp_suspend_cond_attr;
Jim Cownie5e8470a2013-09-27 10:38:44 +000088static pthread_mutexattr_t __kmp_suspend_mutex_attr;
89
Jonathan Peyton30419822017-05-12 18:01:32 +000090static kmp_cond_align_t __kmp_wait_cv;
91static kmp_mutex_align_t __kmp_wait_mx;
Jim Cownie5e8470a2013-09-27 10:38:44 +000092
Jonathan Peyton35d75ae2017-03-20 22:11:31 +000093kmp_uint64 __kmp_ticks_per_msec = 1000000;
Jonathan Peytonb66d1aa2016-09-27 17:11:17 +000094
Jim Cownie5e8470a2013-09-27 10:38:44 +000095#ifdef DEBUG_SUSPEND
Jonathan Peyton30419822017-05-12 18:01:32 +000096static void __kmp_print_cond(char *buffer, kmp_cond_align_t *cond) {
97 KMP_SNPRINTF(buffer, 128, "(cond (lock (%ld, %d)), (descr (%p)))",
98 cond->c_cond.__c_lock.__status, cond->c_cond.__c_lock.__spinlock,
99 cond->c_cond.__c_waiting);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000100}
101#endif
102
Jonathan Peyton30419822017-05-12 18:01:32 +0000103#if (KMP_OS_LINUX && KMP_AFFINITY_SUPPORTED)
Jim Cownie5e8470a2013-09-27 10:38:44 +0000104
Jonathan Peyton30419822017-05-12 18:01:32 +0000105/* Affinity support */
Jim Cownie5e8470a2013-09-27 10:38:44 +0000106
Jonathan Peyton30419822017-05-12 18:01:32 +0000107void __kmp_affinity_bind_thread(int which) {
108 KMP_ASSERT2(KMP_AFFINITY_CAPABLE(),
109 "Illegal set affinity operation when not capable");
Jim Cownie5e8470a2013-09-27 10:38:44 +0000110
Jonathan Peyton30419822017-05-12 18:01:32 +0000111 kmp_affin_mask_t *mask;
112 KMP_CPU_ALLOC_ON_STACK(mask);
113 KMP_CPU_ZERO(mask);
114 KMP_CPU_SET(which, mask);
115 __kmp_set_system_affinity(mask, TRUE);
116 KMP_CPU_FREE_FROM_STACK(mask);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000117}
118
Jonathan Peyton30419822017-05-12 18:01:32 +0000119/* Determine if we can access affinity functionality on this version of
Jim Cownie5e8470a2013-09-27 10:38:44 +0000120 * Linux* OS by checking __NR_sched_{get,set}affinity system calls, and set
Jonathan Peyton30419822017-05-12 18:01:32 +0000121 * __kmp_affin_mask_size to the appropriate value (0 means not capable). */
122void __kmp_affinity_determine_capable(const char *env_var) {
123// Check and see if the OS supports thread affinity.
124
125#define KMP_CPU_SET_SIZE_LIMIT (1024 * 1024)
126
127 int gCode;
128 int sCode;
129 unsigned char *buf;
130 buf = (unsigned char *)KMP_INTERNAL_MALLOC(KMP_CPU_SET_SIZE_LIMIT);
131
132 // If Linux* OS:
133 // If the syscall fails or returns a suggestion for the size,
134 // then we don't have to search for an appropriate size.
135 gCode = syscall(__NR_sched_getaffinity, 0, KMP_CPU_SET_SIZE_LIMIT, buf);
136 KA_TRACE(30, ("__kmp_affinity_determine_capable: "
137 "initial getaffinity call returned %d errno = %d\n",
138 gCode, errno));
139
140 // if ((gCode < 0) && (errno == ENOSYS))
141 if (gCode < 0) {
142 // System call not supported
143 if (__kmp_affinity_verbose ||
144 (__kmp_affinity_warnings && (__kmp_affinity_type != affinity_none) &&
145 (__kmp_affinity_type != affinity_default) &&
146 (__kmp_affinity_type != affinity_disabled))) {
147 int error = errno;
148 kmp_msg_t err_code = KMP_ERR(error);
149 __kmp_msg(kmp_ms_warning, KMP_MSG(GetAffSysCallNotSupported, env_var),
150 err_code, __kmp_msg_null);
151 if (__kmp_generate_warnings == kmp_warnings_off) {
152 __kmp_str_free(&err_code.str);
153 }
154 }
155 KMP_AFFINITY_DISABLE();
156 KMP_INTERNAL_FREE(buf);
157 return;
158 }
159 if (gCode > 0) { // Linux* OS only
160 // The optimal situation: the OS returns the size of the buffer it expects.
Jim Cownie5e8470a2013-09-27 10:38:44 +0000161 //
Jonathan Peyton30419822017-05-12 18:01:32 +0000162 // A verification of correct behavior is that Isetaffinity on a NULL
163 // buffer with the same size fails with errno set to EFAULT.
164 sCode = syscall(__NR_sched_setaffinity, 0, gCode, NULL);
165 KA_TRACE(30, ("__kmp_affinity_determine_capable: "
166 "setaffinity for mask size %d returned %d errno = %d\n",
167 gCode, sCode, errno));
168 if (sCode < 0) {
169 if (errno == ENOSYS) {
170 if (__kmp_affinity_verbose ||
171 (__kmp_affinity_warnings &&
172 (__kmp_affinity_type != affinity_none) &&
173 (__kmp_affinity_type != affinity_default) &&
174 (__kmp_affinity_type != affinity_disabled))) {
175 int error = errno;
176 kmp_msg_t err_code = KMP_ERR(error);
177 __kmp_msg(kmp_ms_warning, KMP_MSG(SetAffSysCallNotSupported, env_var),
178 err_code, __kmp_msg_null);
179 if (__kmp_generate_warnings == kmp_warnings_off) {
180 __kmp_str_free(&err_code.str);
181 }
182 }
183 KMP_AFFINITY_DISABLE();
184 KMP_INTERNAL_FREE(buf);
185 }
186 if (errno == EFAULT) {
187 KMP_AFFINITY_ENABLE(gCode);
188 KA_TRACE(10, ("__kmp_affinity_determine_capable: "
189 "affinity supported (mask size %d)\n",
190 (int)__kmp_affin_mask_size));
191 KMP_INTERNAL_FREE(buf);
192 return;
193 }
194 }
195 }
Jim Cownie5e8470a2013-09-27 10:38:44 +0000196
Jonathan Peyton30419822017-05-12 18:01:32 +0000197 // Call the getaffinity system call repeatedly with increasing set sizes
198 // until we succeed, or reach an upper bound on the search.
199 KA_TRACE(30, ("__kmp_affinity_determine_capable: "
200 "searching for proper set size\n"));
201 int size;
202 for (size = 1; size <= KMP_CPU_SET_SIZE_LIMIT; size *= 2) {
203 gCode = syscall(__NR_sched_getaffinity, 0, size, buf);
204 KA_TRACE(30, ("__kmp_affinity_determine_capable: "
205 "getaffinity for mask size %d returned %d errno = %d\n",
206 size, gCode, errno));
Jim Cownie5e8470a2013-09-27 10:38:44 +0000207
Jim Cownie5e8470a2013-09-27 10:38:44 +0000208 if (gCode < 0) {
Jonathan Peyton30419822017-05-12 18:01:32 +0000209 if (errno == ENOSYS) {
210 // We shouldn't get here
211 KA_TRACE(30, ("__kmp_affinity_determine_capable: "
212 "inconsistent OS call behavior: errno == ENOSYS for mask "
213 "size %d\n",
214 size));
215 if (__kmp_affinity_verbose ||
216 (__kmp_affinity_warnings &&
217 (__kmp_affinity_type != affinity_none) &&
218 (__kmp_affinity_type != affinity_default) &&
219 (__kmp_affinity_type != affinity_disabled))) {
220 int error = errno;
221 kmp_msg_t err_code = KMP_ERR(error);
222 __kmp_msg(kmp_ms_warning, KMP_MSG(GetAffSysCallNotSupported, env_var),
223 err_code, __kmp_msg_null);
224 if (__kmp_generate_warnings == kmp_warnings_off) {
225 __kmp_str_free(&err_code.str);
226 }
Jim Cownie5e8470a2013-09-27 10:38:44 +0000227 }
Andrey Churbanov1f037e42015-03-10 09:15:26 +0000228 KMP_AFFINITY_DISABLE();
Jim Cownie5e8470a2013-09-27 10:38:44 +0000229 KMP_INTERNAL_FREE(buf);
230 return;
Jonathan Peyton30419822017-05-12 18:01:32 +0000231 }
232 continue;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000233 }
Jonathan Peyton30419822017-05-12 18:01:32 +0000234
235 sCode = syscall(__NR_sched_setaffinity, 0, gCode, NULL);
236 KA_TRACE(30, ("__kmp_affinity_determine_capable: "
237 "setaffinity for mask size %d returned %d errno = %d\n",
238 gCode, sCode, errno));
239 if (sCode < 0) {
240 if (errno == ENOSYS) { // Linux* OS only
241 // We shouldn't get here
242 KA_TRACE(30, ("__kmp_affinity_determine_capable: "
243 "inconsistent OS call behavior: errno == ENOSYS for mask "
244 "size %d\n",
245 size));
246 if (__kmp_affinity_verbose ||
247 (__kmp_affinity_warnings &&
248 (__kmp_affinity_type != affinity_none) &&
249 (__kmp_affinity_type != affinity_default) &&
250 (__kmp_affinity_type != affinity_disabled))) {
251 int error = errno;
252 kmp_msg_t err_code = KMP_ERR(error);
253 __kmp_msg(kmp_ms_warning, KMP_MSG(SetAffSysCallNotSupported, env_var),
254 err_code, __kmp_msg_null);
255 if (__kmp_generate_warnings == kmp_warnings_off) {
256 __kmp_str_free(&err_code.str);
257 }
Jim Cownie5e8470a2013-09-27 10:38:44 +0000258 }
Jonathan Peyton30419822017-05-12 18:01:32 +0000259 KMP_AFFINITY_DISABLE();
260 KMP_INTERNAL_FREE(buf);
261 return;
262 }
263 if (errno == EFAULT) {
264 KMP_AFFINITY_ENABLE(gCode);
265 KA_TRACE(10, ("__kmp_affinity_determine_capable: "
266 "affinity supported (mask size %d)\n",
267 (int)__kmp_affin_mask_size));
268 KMP_INTERNAL_FREE(buf);
269 return;
270 }
Jim Cownie5e8470a2013-09-27 10:38:44 +0000271 }
Jonathan Peyton30419822017-05-12 18:01:32 +0000272 }
273 // save uncaught error code
274 // int error = errno;
275 KMP_INTERNAL_FREE(buf);
276 // restore uncaught error code, will be printed at the next KMP_WARNING below
277 // errno = error;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000278
Jonathan Peyton30419822017-05-12 18:01:32 +0000279 // Affinity is not supported
280 KMP_AFFINITY_DISABLE();
281 KA_TRACE(10, ("__kmp_affinity_determine_capable: "
282 "cannot determine mask size - affinity not supported\n"));
283 if (__kmp_affinity_verbose ||
284 (__kmp_affinity_warnings && (__kmp_affinity_type != affinity_none) &&
285 (__kmp_affinity_type != affinity_default) &&
286 (__kmp_affinity_type != affinity_disabled))) {
287 KMP_WARNING(AffCantGetMaskSize, env_var);
288 }
Jim Cownie5e8470a2013-09-27 10:38:44 +0000289}
290
Andrey Churbanovd39f11c2015-03-10 10:14:57 +0000291#endif // KMP_OS_LINUX && KMP_AFFINITY_SUPPORTED
Jim Cownie5e8470a2013-09-27 10:38:44 +0000292
Jonathan Peyton9d2412c2016-06-22 16:35:12 +0000293#if KMP_USE_FUTEX
Andrey Churbanovd39f11c2015-03-10 10:14:57 +0000294
Jonathan Peyton30419822017-05-12 18:01:32 +0000295int __kmp_futex_determine_capable() {
296 int loc = 0;
297 int rc = syscall(__NR_futex, &loc, FUTEX_WAKE, 1, NULL, NULL, 0);
298 int retval = (rc == 0) || (errno != ENOSYS);
Andrey Churbanovd39f11c2015-03-10 10:14:57 +0000299
Jonathan Peyton30419822017-05-12 18:01:32 +0000300 KA_TRACE(10,
301 ("__kmp_futex_determine_capable: rc = %d errno = %d\n", rc, errno));
302 KA_TRACE(10, ("__kmp_futex_determine_capable: futex syscall%s supported\n",
303 retval ? "" : " not"));
Andrey Churbanovd39f11c2015-03-10 10:14:57 +0000304
Jonathan Peyton30419822017-05-12 18:01:32 +0000305 return retval;
Andrey Churbanovd39f11c2015-03-10 10:14:57 +0000306}
307
Jonathan Peyton9d2412c2016-06-22 16:35:12 +0000308#endif // KMP_USE_FUTEX
Andrey Churbanovd39f11c2015-03-10 10:14:57 +0000309
Jonathan Peyton30419822017-05-12 18:01:32 +0000310#if (KMP_ARCH_X86 || KMP_ARCH_X86_64) && (!KMP_ASM_INTRINS)
311/* Only 32-bit "add-exchange" instruction on IA-32 architecture causes us to
312 use compare_and_store for these routines */
Andrey Churbanovd39f11c2015-03-10 10:14:57 +0000313
Jonathan Peyton30419822017-05-12 18:01:32 +0000314kmp_int8 __kmp_test_then_or8(volatile kmp_int8 *p, kmp_int8 d) {
315 kmp_int8 old_value, new_value;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000316
Jonathan Peyton30419822017-05-12 18:01:32 +0000317 old_value = TCR_1(*p);
318 new_value = old_value | d;
Andrey Churbanov7b2ab712015-03-10 09:03:42 +0000319
Jonathan Peyton30419822017-05-12 18:01:32 +0000320 while (!KMP_COMPARE_AND_STORE_REL8(p, old_value, new_value)) {
321 KMP_CPU_PAUSE();
322 old_value = TCR_1(*p);
Andrey Churbanov7b2ab712015-03-10 09:03:42 +0000323 new_value = old_value | d;
Jonathan Peyton30419822017-05-12 18:01:32 +0000324 }
325 return old_value;
Andrey Churbanov7b2ab712015-03-10 09:03:42 +0000326}
327
Jonathan Peyton30419822017-05-12 18:01:32 +0000328kmp_int8 __kmp_test_then_and8(volatile kmp_int8 *p, kmp_int8 d) {
329 kmp_int8 old_value, new_value;
Andrey Churbanov7b2ab712015-03-10 09:03:42 +0000330
Jonathan Peyton30419822017-05-12 18:01:32 +0000331 old_value = TCR_1(*p);
332 new_value = old_value & d;
333
334 while (!KMP_COMPARE_AND_STORE_REL8(p, old_value, new_value)) {
335 KMP_CPU_PAUSE();
336 old_value = TCR_1(*p);
Andrey Churbanov7b2ab712015-03-10 09:03:42 +0000337 new_value = old_value & d;
Jonathan Peyton30419822017-05-12 18:01:32 +0000338 }
339 return old_value;
Andrey Churbanov7b2ab712015-03-10 09:03:42 +0000340}
341
Andrey Churbanov5ba90c72017-07-17 09:03:14 +0000342kmp_uint32 __kmp_test_then_or32(volatile kmp_uint32 *p, kmp_uint32 d) {
343 kmp_uint32 old_value, new_value;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000344
Jonathan Peyton30419822017-05-12 18:01:32 +0000345 old_value = TCR_4(*p);
346 new_value = old_value | d;
347
348 while (!KMP_COMPARE_AND_STORE_REL32(p, old_value, new_value)) {
349 KMP_CPU_PAUSE();
350 old_value = TCR_4(*p);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000351 new_value = old_value | d;
Jonathan Peyton30419822017-05-12 18:01:32 +0000352 }
353 return old_value;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000354}
355
Andrey Churbanov5ba90c72017-07-17 09:03:14 +0000356kmp_uint32 __kmp_test_then_and32(volatile kmp_uint32 *p, kmp_uint32 d) {
357 kmp_uint32 old_value, new_value;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000358
Jonathan Peyton30419822017-05-12 18:01:32 +0000359 old_value = TCR_4(*p);
360 new_value = old_value & d;
361
362 while (!KMP_COMPARE_AND_STORE_REL32(p, old_value, new_value)) {
363 KMP_CPU_PAUSE();
364 old_value = TCR_4(*p);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000365 new_value = old_value & d;
Jonathan Peyton30419822017-05-12 18:01:32 +0000366 }
367 return old_value;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000368}
369
Jonathan Peyton30419822017-05-12 18:01:32 +0000370#if KMP_ARCH_X86
371kmp_int8 __kmp_test_then_add8(volatile kmp_int8 *p, kmp_int8 d) {
372 kmp_int8 old_value, new_value;
Andrey Churbanovd39f11c2015-03-10 10:14:57 +0000373
Jonathan Peyton30419822017-05-12 18:01:32 +0000374 old_value = TCR_1(*p);
375 new_value = old_value + d;
376
377 while (!KMP_COMPARE_AND_STORE_REL8(p, old_value, new_value)) {
378 KMP_CPU_PAUSE();
379 old_value = TCR_1(*p);
Andrey Churbanovd39f11c2015-03-10 10:14:57 +0000380 new_value = old_value + d;
Jonathan Peyton30419822017-05-12 18:01:32 +0000381 }
382 return old_value;
Andrey Churbanovd39f11c2015-03-10 10:14:57 +0000383}
384
Jonathan Peyton30419822017-05-12 18:01:32 +0000385kmp_int64 __kmp_test_then_add64(volatile kmp_int64 *p, kmp_int64 d) {
386 kmp_int64 old_value, new_value;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000387
Jonathan Peyton30419822017-05-12 18:01:32 +0000388 old_value = TCR_8(*p);
389 new_value = old_value + d;
390
391 while (!KMP_COMPARE_AND_STORE_REL64(p, old_value, new_value)) {
392 KMP_CPU_PAUSE();
393 old_value = TCR_8(*p);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000394 new_value = old_value + d;
Jonathan Peyton30419822017-05-12 18:01:32 +0000395 }
396 return old_value;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000397}
Jonathan Peyton30419822017-05-12 18:01:32 +0000398#endif /* KMP_ARCH_X86 */
Jim Cownie5e8470a2013-09-27 10:38:44 +0000399
Andrey Churbanov5ba90c72017-07-17 09:03:14 +0000400kmp_uint64 __kmp_test_then_or64(volatile kmp_uint64 *p, kmp_uint64 d) {
401 kmp_uint64 old_value, new_value;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000402
Jonathan Peyton30419822017-05-12 18:01:32 +0000403 old_value = TCR_8(*p);
404 new_value = old_value | d;
405 while (!KMP_COMPARE_AND_STORE_REL64(p, old_value, new_value)) {
406 KMP_CPU_PAUSE();
407 old_value = TCR_8(*p);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000408 new_value = old_value | d;
Jonathan Peyton30419822017-05-12 18:01:32 +0000409 }
410 return old_value;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000411}
412
Andrey Churbanov5ba90c72017-07-17 09:03:14 +0000413kmp_uint64 __kmp_test_then_and64(volatile kmp_uint64 *p, kmp_uint64 d) {
414 kmp_uint64 old_value, new_value;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000415
Jonathan Peyton30419822017-05-12 18:01:32 +0000416 old_value = TCR_8(*p);
417 new_value = old_value & d;
418 while (!KMP_COMPARE_AND_STORE_REL64(p, old_value, new_value)) {
419 KMP_CPU_PAUSE();
420 old_value = TCR_8(*p);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000421 new_value = old_value & d;
Jonathan Peyton30419822017-05-12 18:01:32 +0000422 }
423 return old_value;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000424}
425
426#endif /* (KMP_ARCH_X86 || KMP_ARCH_X86_64) && (! KMP_ASM_INTRINS) */
427
Jonathan Peyton30419822017-05-12 18:01:32 +0000428void __kmp_terminate_thread(int gtid) {
429 int status;
430 kmp_info_t *th = __kmp_threads[gtid];
Jim Cownie5e8470a2013-09-27 10:38:44 +0000431
Jonathan Peyton30419822017-05-12 18:01:32 +0000432 if (!th)
433 return;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000434
Jonathan Peyton30419822017-05-12 18:01:32 +0000435#ifdef KMP_CANCEL_THREADS
436 KA_TRACE(10, ("__kmp_terminate_thread: kill (%d)\n", gtid));
437 status = pthread_cancel(th->th.th_info.ds.ds_thread);
438 if (status != 0 && status != ESRCH) {
Jonathan Peyton6a393f72017-09-05 15:43:58 +0000439 __kmp_fatal(KMP_MSG(CantTerminateWorkerThread), KMP_ERR(status),
440 __kmp_msg_null);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +0000441 }
Jonathan Peyton30419822017-05-12 18:01:32 +0000442#endif
Jonathan Peytone47d32f2019-02-28 19:11:29 +0000443 KMP_YIELD(TRUE);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000444} //
445
Jonathan Peyton30419822017-05-12 18:01:32 +0000446/* Set thread stack info according to values returned by pthread_getattr_np().
447 If values are unreasonable, assume call failed and use incremental stack
448 refinement method instead. Returns TRUE if the stack parameters could be
449 determined exactly, FALSE if incremental refinement is necessary. */
450static kmp_int32 __kmp_set_stack_info(int gtid, kmp_info_t *th) {
451 int stack_data;
Kamil Rytarowskia56ac942018-12-09 16:40:33 +0000452#if KMP_OS_LINUX || KMP_OS_DRAGONFLY || KMP_OS_FREEBSD || KMP_OS_NETBSD || \
453 KMP_OS_HURD
Jonathan Peyton30419822017-05-12 18:01:32 +0000454 pthread_attr_t attr;
455 int status;
456 size_t size = 0;
457 void *addr = 0;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000458
Jonathan Peyton30419822017-05-12 18:01:32 +0000459 /* Always do incremental stack refinement for ubermaster threads since the
460 initial thread stack range can be reduced by sibling thread creation so
461 pthread_attr_getstack may cause thread gtid aliasing */
462 if (!KMP_UBER_GTID(gtid)) {
Jim Cownie5e8470a2013-09-27 10:38:44 +0000463
Jonathan Peyton30419822017-05-12 18:01:32 +0000464 /* Fetch the real thread attributes */
465 status = pthread_attr_init(&attr);
466 KMP_CHECK_SYSFAIL("pthread_attr_init", status);
Kamil Rytarowskia56ac942018-12-09 16:40:33 +0000467#if KMP_OS_DRAGONFLY || KMP_OS_FREEBSD || KMP_OS_NETBSD
Jonathan Peyton30419822017-05-12 18:01:32 +0000468 status = pthread_attr_get_np(pthread_self(), &attr);
469 KMP_CHECK_SYSFAIL("pthread_attr_get_np", status);
Alp Toker763b9392014-02-28 09:42:41 +0000470#else
Jonathan Peyton30419822017-05-12 18:01:32 +0000471 status = pthread_getattr_np(pthread_self(), &attr);
472 KMP_CHECK_SYSFAIL("pthread_getattr_np", status);
Alp Toker763b9392014-02-28 09:42:41 +0000473#endif
Jonathan Peyton30419822017-05-12 18:01:32 +0000474 status = pthread_attr_getstack(&attr, &addr, &size);
475 KMP_CHECK_SYSFAIL("pthread_attr_getstack", status);
476 KA_TRACE(60,
477 ("__kmp_set_stack_info: T#%d pthread_attr_getstack returned size:"
478 " %lu, low addr: %p\n",
479 gtid, size, addr));
480 status = pthread_attr_destroy(&attr);
481 KMP_CHECK_SYSFAIL("pthread_attr_destroy", status);
482 }
Jim Cownie5e8470a2013-09-27 10:38:44 +0000483
Jonathan Peyton30419822017-05-12 18:01:32 +0000484 if (size != 0 && addr != 0) { // was stack parameter determination successful?
485 /* Store the correct base and size */
486 TCW_PTR(th->th.th_info.ds.ds_stackbase, (((char *)addr) + size));
487 TCW_PTR(th->th.th_info.ds.ds_stacksize, size);
488 TCW_4(th->th.th_info.ds.ds_stackgrow, FALSE);
489 return TRUE;
490 }
Kamil Rytarowskia56ac942018-12-09 16:40:33 +0000491#endif /* KMP_OS_LINUX || KMP_OS_DRAGONFLY || KMP_OS_FREEBSD || KMP_OS_NETBSD ||
492 KMP_OS_HURD */
Jonathan Peyton30419822017-05-12 18:01:32 +0000493 /* Use incremental refinement starting from initial conservative estimate */
494 TCW_PTR(th->th.th_info.ds.ds_stacksize, 0);
495 TCW_PTR(th->th.th_info.ds.ds_stackbase, &stack_data);
496 TCW_4(th->th.th_info.ds.ds_stackgrow, TRUE);
497 return FALSE;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000498}
499
Jonathan Peyton30419822017-05-12 18:01:32 +0000500static void *__kmp_launch_worker(void *thr) {
501 int status, old_type, old_state;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000502#ifdef KMP_BLOCK_SIGNALS
Jonathan Peyton30419822017-05-12 18:01:32 +0000503 sigset_t new_set, old_set;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000504#endif /* KMP_BLOCK_SIGNALS */
Jonathan Peyton30419822017-05-12 18:01:32 +0000505 void *exit_val;
Kamil Rytarowskia56ac942018-12-09 16:40:33 +0000506#if KMP_OS_LINUX || KMP_OS_DRAGONFLY || KMP_OS_FREEBSD || KMP_OS_NETBSD || \
Kamil Rytarowski7e1ea992018-12-09 16:46:48 +0000507 KMP_OS_OPENBSD || KMP_OS_HURD
Jonathan Peyton30419822017-05-12 18:01:32 +0000508 void *volatile padding = 0;
Jonathan Peyton2321d572015-06-08 19:25:25 +0000509#endif
Jonathan Peyton30419822017-05-12 18:01:32 +0000510 int gtid;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000511
Jonathan Peyton30419822017-05-12 18:01:32 +0000512 gtid = ((kmp_info_t *)thr)->th.th_info.ds.ds_gtid;
513 __kmp_gtid_set_specific(gtid);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000514#ifdef KMP_TDATA_GTID
Jonathan Peyton30419822017-05-12 18:01:32 +0000515 __kmp_gtid = gtid;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000516#endif
Jim Cownie4cc4bb42014-10-07 16:25:50 +0000517#if KMP_STATS_ENABLED
Jonathan Peyton40039ac2017-11-07 23:32:13 +0000518 // set thread local index to point to thread-specific stats
Jonathan Peyton30419822017-05-12 18:01:32 +0000519 __kmp_stats_thread_ptr = ((kmp_info_t *)thr)->th.th_stats;
Jonathan Peytonf0682ac2018-07-30 17:41:08 +0000520 __kmp_stats_thread_ptr->startLife();
Jonathan Peyton30419822017-05-12 18:01:32 +0000521 KMP_SET_THREAD_STATE(IDLE);
522 KMP_INIT_PARTITIONED_TIMERS(OMP_idle);
Jim Cownie4cc4bb42014-10-07 16:25:50 +0000523#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +0000524
525#if USE_ITT_BUILD
Jonathan Peyton30419822017-05-12 18:01:32 +0000526 __kmp_itt_thread_name(gtid);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000527#endif /* USE_ITT_BUILD */
528
Alp Toker763b9392014-02-28 09:42:41 +0000529#if KMP_AFFINITY_SUPPORTED
Jonathan Peyton30419822017-05-12 18:01:32 +0000530 __kmp_affinity_set_init_mask(gtid, FALSE);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000531#endif
532
533#ifdef KMP_CANCEL_THREADS
Jonathan Peyton30419822017-05-12 18:01:32 +0000534 status = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old_type);
535 KMP_CHECK_SYSFAIL("pthread_setcanceltype", status);
536 // josh todo: isn't PTHREAD_CANCEL_ENABLE default for newly-created threads?
537 status = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_state);
538 KMP_CHECK_SYSFAIL("pthread_setcancelstate", status);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000539#endif
540
541#if KMP_ARCH_X86 || KMP_ARCH_X86_64
Jonathan Peyton30419822017-05-12 18:01:32 +0000542 // Set FP control regs to be a copy of the parallel initialization thread's.
543 __kmp_clear_x87_fpu_status_word();
544 __kmp_load_x87_fpu_control_word(&__kmp_init_x87_fpu_control_word);
545 __kmp_load_mxcsr(&__kmp_init_mxcsr);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000546#endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
547
548#ifdef KMP_BLOCK_SIGNALS
Jonathan Peyton30419822017-05-12 18:01:32 +0000549 status = sigfillset(&new_set);
550 KMP_CHECK_SYSFAIL_ERRNO("sigfillset", status);
551 status = pthread_sigmask(SIG_BLOCK, &new_set, &old_set);
552 KMP_CHECK_SYSFAIL("pthread_sigmask", status);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000553#endif /* KMP_BLOCK_SIGNALS */
554
Kamil Rytarowski7e1ea992018-12-09 16:46:48 +0000555#if KMP_OS_LINUX || KMP_OS_DRAGONFLY || KMP_OS_FREEBSD || KMP_OS_NETBSD || \
556 KMP_OS_OPENBSD
Jonathan Peyton30419822017-05-12 18:01:32 +0000557 if (__kmp_stkoffset > 0 && gtid > 0) {
558 padding = KMP_ALLOCA(gtid * __kmp_stkoffset);
559 }
Jim Cownie5e8470a2013-09-27 10:38:44 +0000560#endif
561
Jonathan Peyton30419822017-05-12 18:01:32 +0000562 KMP_MB();
563 __kmp_set_stack_info(gtid, (kmp_info_t *)thr);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000564
Jonathan Peyton30419822017-05-12 18:01:32 +0000565 __kmp_check_stack_overlap((kmp_info_t *)thr);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000566
Jonathan Peyton30419822017-05-12 18:01:32 +0000567 exit_val = __kmp_launch_thread((kmp_info_t *)thr);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000568
569#ifdef KMP_BLOCK_SIGNALS
Jonathan Peyton30419822017-05-12 18:01:32 +0000570 status = pthread_sigmask(SIG_SETMASK, &old_set, NULL);
571 KMP_CHECK_SYSFAIL("pthread_sigmask", status);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000572#endif /* KMP_BLOCK_SIGNALS */
573
Jonathan Peyton30419822017-05-12 18:01:32 +0000574 return exit_val;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000575}
576
Jonathan Peytonb66d1aa2016-09-27 17:11:17 +0000577#if KMP_USE_MONITOR
Jim Cownie5e8470a2013-09-27 10:38:44 +0000578/* The monitor thread controls all of the threads in the complex */
579
Jonathan Peyton30419822017-05-12 18:01:32 +0000580static void *__kmp_launch_monitor(void *thr) {
581 int status, old_type, old_state;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000582#ifdef KMP_BLOCK_SIGNALS
Jonathan Peyton30419822017-05-12 18:01:32 +0000583 sigset_t new_set;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000584#endif /* KMP_BLOCK_SIGNALS */
Jonathan Peyton30419822017-05-12 18:01:32 +0000585 struct timespec interval;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000586
Jonathan Peyton30419822017-05-12 18:01:32 +0000587 KMP_MB(); /* Flush all pending memory write invalidates. */
Jim Cownie5e8470a2013-09-27 10:38:44 +0000588
Jonathan Peyton30419822017-05-12 18:01:32 +0000589 KA_TRACE(10, ("__kmp_launch_monitor: #1 launched\n"));
Jim Cownie5e8470a2013-09-27 10:38:44 +0000590
Jonathan Peyton30419822017-05-12 18:01:32 +0000591 /* register us as the monitor thread */
592 __kmp_gtid_set_specific(KMP_GTID_MONITOR);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000593#ifdef KMP_TDATA_GTID
Jonathan Peyton30419822017-05-12 18:01:32 +0000594 __kmp_gtid = KMP_GTID_MONITOR;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000595#endif
596
Jonathan Peyton30419822017-05-12 18:01:32 +0000597 KMP_MB();
Jim Cownie5e8470a2013-09-27 10:38:44 +0000598
599#if USE_ITT_BUILD
Jonathan Peyton30419822017-05-12 18:01:32 +0000600 // Instruct Intel(R) Threading Tools to ignore monitor thread.
601 __kmp_itt_thread_ignore();
Jim Cownie5e8470a2013-09-27 10:38:44 +0000602#endif /* USE_ITT_BUILD */
603
Jonathan Peyton30419822017-05-12 18:01:32 +0000604 __kmp_set_stack_info(((kmp_info_t *)thr)->th.th_info.ds.ds_gtid,
605 (kmp_info_t *)thr);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000606
Jonathan Peyton30419822017-05-12 18:01:32 +0000607 __kmp_check_stack_overlap((kmp_info_t *)thr);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000608
609#ifdef KMP_CANCEL_THREADS
Jonathan Peyton30419822017-05-12 18:01:32 +0000610 status = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old_type);
611 KMP_CHECK_SYSFAIL("pthread_setcanceltype", status);
612 // josh todo: isn't PTHREAD_CANCEL_ENABLE default for newly-created threads?
613 status = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_state);
614 KMP_CHECK_SYSFAIL("pthread_setcancelstate", status);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000615#endif
616
Jonathan Peyton30419822017-05-12 18:01:32 +0000617#if KMP_REAL_TIME_FIX
618 // This is a potential fix which allows application with real-time scheduling
619 // policy work. However, decision about the fix is not made yet, so it is
620 // disabled by default.
621 { // Are program started with real-time scheduling policy?
622 int sched = sched_getscheduler(0);
623 if (sched == SCHED_FIFO || sched == SCHED_RR) {
624 // Yes, we are a part of real-time application. Try to increase the
625 // priority of the monitor.
626 struct sched_param param;
627 int max_priority = sched_get_priority_max(sched);
628 int rc;
629 KMP_WARNING(RealTimeSchedNotSupported);
630 sched_getparam(0, &param);
631 if (param.sched_priority < max_priority) {
632 param.sched_priority += 1;
633 rc = sched_setscheduler(0, sched, &param);
634 if (rc != 0) {
635 int error = errno;
636 kmp_msg_t err_code = KMP_ERR(error);
637 __kmp_msg(kmp_ms_warning, KMP_MSG(CantChangeMonitorPriority),
638 err_code, KMP_MSG(MonitorWillStarve), __kmp_msg_null);
639 if (__kmp_generate_warnings == kmp_warnings_off) {
640 __kmp_str_free(&err_code.str);
641 }
Jonathan Peytonbd3a7632017-09-27 20:36:27 +0000642 }
Jonathan Peyton30419822017-05-12 18:01:32 +0000643 } else {
644 // We cannot abort here, because number of CPUs may be enough for all
645 // the threads, including the monitor thread, so application could
646 // potentially work...
647 __kmp_msg(kmp_ms_warning, KMP_MSG(RunningAtMaxPriority),
648 KMP_MSG(MonitorWillStarve), KMP_HNT(RunningAtMaxPriority),
649 __kmp_msg_null);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +0000650 }
651 }
Jonathan Peyton30419822017-05-12 18:01:32 +0000652 // AC: free thread that waits for monitor started
653 TCW_4(__kmp_global.g.g_time.dt.t_value, 0);
654 }
655#endif // KMP_REAL_TIME_FIX
Jim Cownie5e8470a2013-09-27 10:38:44 +0000656
Jonathan Peyton30419822017-05-12 18:01:32 +0000657 KMP_MB(); /* Flush all pending memory write invalidates. */
Jim Cownie5e8470a2013-09-27 10:38:44 +0000658
Jonathan Peyton30419822017-05-12 18:01:32 +0000659 if (__kmp_monitor_wakeups == 1) {
660 interval.tv_sec = 1;
661 interval.tv_nsec = 0;
662 } else {
663 interval.tv_sec = 0;
664 interval.tv_nsec = (KMP_NSEC_PER_SEC / __kmp_monitor_wakeups);
665 }
666
667 KA_TRACE(10, ("__kmp_launch_monitor: #2 monitor\n"));
668
Jonathan Peyton30419822017-05-12 18:01:32 +0000669 while (!TCR_4(__kmp_global.g.g_done)) {
670 struct timespec now;
671 struct timeval tval;
672
673 /* This thread monitors the state of the system */
674
675 KA_TRACE(15, ("__kmp_launch_monitor: update\n"));
676
677 status = gettimeofday(&tval, NULL);
678 KMP_CHECK_SYSFAIL_ERRNO("gettimeofday", status);
679 TIMEVAL_TO_TIMESPEC(&tval, &now);
680
681 now.tv_sec += interval.tv_sec;
682 now.tv_nsec += interval.tv_nsec;
683
684 if (now.tv_nsec >= KMP_NSEC_PER_SEC) {
685 now.tv_sec += 1;
686 now.tv_nsec -= KMP_NSEC_PER_SEC;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000687 }
688
Jonathan Peyton30419822017-05-12 18:01:32 +0000689 status = pthread_mutex_lock(&__kmp_wait_mx.m_mutex);
690 KMP_CHECK_SYSFAIL("pthread_mutex_lock", status);
691 // AC: the monitor should not fall asleep if g_done has been set
692 if (!TCR_4(__kmp_global.g.g_done)) { // check once more under mutex
693 status = pthread_cond_timedwait(&__kmp_wait_cv.c_cond,
694 &__kmp_wait_mx.m_mutex, &now);
695 if (status != 0) {
696 if (status != ETIMEDOUT && status != EINTR) {
697 KMP_SYSFAIL("pthread_cond_timedwait", status);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +0000698 }
699 }
700 }
Jonathan Peyton30419822017-05-12 18:01:32 +0000701 status = pthread_mutex_unlock(&__kmp_wait_mx.m_mutex);
702 KMP_CHECK_SYSFAIL("pthread_mutex_unlock", status);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000703
Jonathan Peyton30419822017-05-12 18:01:32 +0000704 TCW_4(__kmp_global.g.g_time.dt.t_value,
705 TCR_4(__kmp_global.g.g_time.dt.t_value) + 1);
706
707 KMP_MB(); /* Flush all pending memory write invalidates. */
708 }
709
710 KA_TRACE(10, ("__kmp_launch_monitor: #3 cleanup\n"));
Jim Cownie5e8470a2013-09-27 10:38:44 +0000711
712#ifdef KMP_BLOCK_SIGNALS
Jonathan Peyton30419822017-05-12 18:01:32 +0000713 status = sigfillset(&new_set);
714 KMP_CHECK_SYSFAIL_ERRNO("sigfillset", status);
715 status = pthread_sigmask(SIG_UNBLOCK, &new_set, NULL);
716 KMP_CHECK_SYSFAIL("pthread_sigmask", status);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000717#endif /* KMP_BLOCK_SIGNALS */
718
Jonathan Peyton30419822017-05-12 18:01:32 +0000719 KA_TRACE(10, ("__kmp_launch_monitor: #4 finished\n"));
Jim Cownie5e8470a2013-09-27 10:38:44 +0000720
Jonathan Peyton30419822017-05-12 18:01:32 +0000721 if (__kmp_global.g.g_abort != 0) {
722 /* now we need to terminate the worker threads */
723 /* the value of t_abort is the signal we caught */
Jim Cownie5e8470a2013-09-27 10:38:44 +0000724
Jonathan Peyton30419822017-05-12 18:01:32 +0000725 int gtid;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000726
Jonathan Peyton30419822017-05-12 18:01:32 +0000727 KA_TRACE(10, ("__kmp_launch_monitor: #5 terminate sig=%d\n",
728 __kmp_global.g.g_abort));
Jim Cownie5e8470a2013-09-27 10:38:44 +0000729
Jonathan Peyton30419822017-05-12 18:01:32 +0000730 /* terminate the OpenMP worker threads */
731 /* TODO this is not valid for sibling threads!!
732 * the uber master might not be 0 anymore.. */
733 for (gtid = 1; gtid < __kmp_threads_capacity; ++gtid)
734 __kmp_terminate_thread(gtid);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000735
Jonathan Peyton30419822017-05-12 18:01:32 +0000736 __kmp_cleanup();
Jim Cownie5e8470a2013-09-27 10:38:44 +0000737
Jonathan Peyton30419822017-05-12 18:01:32 +0000738 KA_TRACE(10, ("__kmp_launch_monitor: #6 raise sig=%d\n",
739 __kmp_global.g.g_abort));
Jim Cownie5e8470a2013-09-27 10:38:44 +0000740
Jonathan Peyton30419822017-05-12 18:01:32 +0000741 if (__kmp_global.g.g_abort > 0)
742 raise(__kmp_global.g.g_abort);
743 }
Jim Cownie5e8470a2013-09-27 10:38:44 +0000744
Jonathan Peyton30419822017-05-12 18:01:32 +0000745 KA_TRACE(10, ("__kmp_launch_monitor: #7 exit\n"));
Jim Cownie5e8470a2013-09-27 10:38:44 +0000746
Jonathan Peyton30419822017-05-12 18:01:32 +0000747 return thr;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000748}
Jonathan Peytonb66d1aa2016-09-27 17:11:17 +0000749#endif // KMP_USE_MONITOR
Jim Cownie5e8470a2013-09-27 10:38:44 +0000750
Jonathan Peyton30419822017-05-12 18:01:32 +0000751void __kmp_create_worker(int gtid, kmp_info_t *th, size_t stack_size) {
752 pthread_t handle;
753 pthread_attr_t thread_attr;
754 int status;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000755
Jonathan Peyton30419822017-05-12 18:01:32 +0000756 th->th.th_info.ds.ds_gtid = gtid;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000757
Jim Cownie4cc4bb42014-10-07 16:25:50 +0000758#if KMP_STATS_ENABLED
Jonathan Peyton30419822017-05-12 18:01:32 +0000759 // sets up worker thread stats
760 __kmp_acquire_tas_lock(&__kmp_stats_lock, gtid);
Jim Cownie4cc4bb42014-10-07 16:25:50 +0000761
Jonathan Peyton30419822017-05-12 18:01:32 +0000762 // th->th.th_stats is used to transfer thread-specific stats-pointer to
763 // __kmp_launch_worker. So when thread is created (goes into
Jonathan Peyton40039ac2017-11-07 23:32:13 +0000764 // __kmp_launch_worker) it will set its thread local pointer to
Jonathan Peyton30419822017-05-12 18:01:32 +0000765 // th->th.th_stats
766 if (!KMP_UBER_GTID(gtid)) {
767 th->th.th_stats = __kmp_stats_list->push_back(gtid);
768 } else {
769 // For root threads, __kmp_stats_thread_ptr is set in __kmp_register_root(),
770 // so set the th->th.th_stats field to it.
771 th->th.th_stats = __kmp_stats_thread_ptr;
772 }
773 __kmp_release_tas_lock(&__kmp_stats_lock, gtid);
Jim Cownie4cc4bb42014-10-07 16:25:50 +0000774
775#endif // KMP_STATS_ENABLED
776
Jonathan Peyton30419822017-05-12 18:01:32 +0000777 if (KMP_UBER_GTID(gtid)) {
778 KA_TRACE(10, ("__kmp_create_worker: uber thread (%d)\n", gtid));
779 th->th.th_info.ds.ds_thread = pthread_self();
780 __kmp_set_stack_info(gtid, th);
781 __kmp_check_stack_overlap(th);
782 return;
Jonathan Peytonbd3a7632017-09-27 20:36:27 +0000783 }
Jim Cownie5e8470a2013-09-27 10:38:44 +0000784
Jonathan Peyton30419822017-05-12 18:01:32 +0000785 KA_TRACE(10, ("__kmp_create_worker: try to create thread (%d)\n", gtid));
Jim Cownie5e8470a2013-09-27 10:38:44 +0000786
Jonathan Peyton30419822017-05-12 18:01:32 +0000787 KMP_MB(); /* Flush all pending memory write invalidates. */
Jim Cownie5e8470a2013-09-27 10:38:44 +0000788
789#ifdef KMP_THREAD_ATTR
Jonathan Peyton30419822017-05-12 18:01:32 +0000790 status = pthread_attr_init(&thread_attr);
791 if (status != 0) {
Jonathan Peyton6a393f72017-09-05 15:43:58 +0000792 __kmp_fatal(KMP_MSG(CantInitThreadAttrs), KMP_ERR(status), __kmp_msg_null);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +0000793 }
Jonathan Peyton30419822017-05-12 18:01:32 +0000794 status = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE);
795 if (status != 0) {
Jonathan Peyton6a393f72017-09-05 15:43:58 +0000796 __kmp_fatal(KMP_MSG(CantSetWorkerState), KMP_ERR(status), __kmp_msg_null);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +0000797 }
Jim Cownie5e8470a2013-09-27 10:38:44 +0000798
Jonathan Peyton30419822017-05-12 18:01:32 +0000799 /* Set stack size for this thread now.
800 The multiple of 2 is there because on some machines, requesting an unusual
801 stacksize causes the thread to have an offset before the dummy alloca()
802 takes place to create the offset. Since we want the user to have a
803 sufficient stacksize AND support a stack offset, we alloca() twice the
804 offset so that the upcoming alloca() does not eliminate any premade offset,
805 and also gives the user the stack space they requested for all threads */
806 stack_size += gtid * __kmp_stkoffset * 2;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000807
Yi Kong3d21a3a2019-07-25 22:29:55 +0000808#if defined(__ANDROID__) && __ANDROID_API__ < 19
809 // Round the stack size to a multiple of the page size. Older versions of
810 // Android (until KitKat) would fail pthread_attr_setstacksize with EINVAL
811 // if the stack size was not a multiple of the page size.
812 stack_size = (stack_size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
813#endif
814
Jonathan Peyton30419822017-05-12 18:01:32 +0000815 KA_TRACE(10, ("__kmp_create_worker: T#%d, default stacksize = %lu bytes, "
816 "__kmp_stksize = %lu bytes, final stacksize = %lu bytes\n",
817 gtid, KMP_DEFAULT_STKSIZE, __kmp_stksize, stack_size));
Jim Cownie5e8470a2013-09-27 10:38:44 +0000818
Jim Cownie5e8470a2013-09-27 10:38:44 +0000819#ifdef _POSIX_THREAD_ATTR_STACKSIZE
Jonathan Peyton30419822017-05-12 18:01:32 +0000820 status = pthread_attr_setstacksize(&thread_attr, stack_size);
821#ifdef KMP_BACKUP_STKSIZE
822 if (status != 0) {
823 if (!__kmp_env_stksize) {
824 stack_size = KMP_BACKUP_STKSIZE + gtid * __kmp_stkoffset;
825 __kmp_stksize = KMP_BACKUP_STKSIZE;
826 KA_TRACE(10, ("__kmp_create_worker: T#%d, default stacksize = %lu bytes, "
827 "__kmp_stksize = %lu bytes, (backup) final stacksize = %lu "
828 "bytes\n",
829 gtid, KMP_DEFAULT_STKSIZE, __kmp_stksize, stack_size));
830 status = pthread_attr_setstacksize(&thread_attr, stack_size);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +0000831 }
832 }
Jonathan Peyton30419822017-05-12 18:01:32 +0000833#endif /* KMP_BACKUP_STKSIZE */
834 if (status != 0) {
Jonathan Peyton6a393f72017-09-05 15:43:58 +0000835 __kmp_fatal(KMP_MSG(CantSetWorkerStackSize, stack_size), KMP_ERR(status),
836 KMP_HNT(ChangeWorkerStackSize), __kmp_msg_null);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +0000837 }
Jim Cownie5e8470a2013-09-27 10:38:44 +0000838#endif /* _POSIX_THREAD_ATTR_STACKSIZE */
Jim Cownie5e8470a2013-09-27 10:38:44 +0000839
Jim Cownie5e8470a2013-09-27 10:38:44 +0000840#endif /* KMP_THREAD_ATTR */
841
Jonathan Peyton30419822017-05-12 18:01:32 +0000842 status =
843 pthread_create(&handle, &thread_attr, __kmp_launch_worker, (void *)th);
844 if (status != 0 || !handle) { // ??? Why do we check handle??
845#ifdef _POSIX_THREAD_ATTR_STACKSIZE
846 if (status == EINVAL) {
Jonathan Peyton6a393f72017-09-05 15:43:58 +0000847 __kmp_fatal(KMP_MSG(CantSetWorkerStackSize, stack_size), KMP_ERR(status),
848 KMP_HNT(IncreaseWorkerStackSize), __kmp_msg_null);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +0000849 }
Jonathan Peyton30419822017-05-12 18:01:32 +0000850 if (status == ENOMEM) {
Jonathan Peyton6a393f72017-09-05 15:43:58 +0000851 __kmp_fatal(KMP_MSG(CantSetWorkerStackSize, stack_size), KMP_ERR(status),
852 KMP_HNT(DecreaseWorkerStackSize), __kmp_msg_null);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +0000853 }
Jonathan Peyton30419822017-05-12 18:01:32 +0000854#endif /* _POSIX_THREAD_ATTR_STACKSIZE */
855 if (status == EAGAIN) {
Jonathan Peyton6a393f72017-09-05 15:43:58 +0000856 __kmp_fatal(KMP_MSG(NoResourcesForWorkerThread), KMP_ERR(status),
857 KMP_HNT(Decrease_NUM_THREADS), __kmp_msg_null);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +0000858 }
Jonathan Peyton30419822017-05-12 18:01:32 +0000859 KMP_SYSFAIL("pthread_create", status);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +0000860 }
Jim Cownie5e8470a2013-09-27 10:38:44 +0000861
Jonathan Peyton30419822017-05-12 18:01:32 +0000862 th->th.th_info.ds.ds_thread = handle;
863
864#ifdef KMP_THREAD_ATTR
865 status = pthread_attr_destroy(&thread_attr);
866 if (status) {
867 kmp_msg_t err_code = KMP_ERR(status);
868 __kmp_msg(kmp_ms_warning, KMP_MSG(CantDestroyThreadAttrs), err_code,
869 __kmp_msg_null);
870 if (__kmp_generate_warnings == kmp_warnings_off) {
871 __kmp_str_free(&err_code.str);
872 }
Jonathan Peytonbd3a7632017-09-27 20:36:27 +0000873 }
Jonathan Peyton30419822017-05-12 18:01:32 +0000874#endif /* KMP_THREAD_ATTR */
875
876 KMP_MB(); /* Flush all pending memory write invalidates. */
877
878 KA_TRACE(10, ("__kmp_create_worker: done creating thread (%d)\n", gtid));
Jim Cownie5e8470a2013-09-27 10:38:44 +0000879
880} // __kmp_create_worker
881
Jonathan Peytonb66d1aa2016-09-27 17:11:17 +0000882#if KMP_USE_MONITOR
Jonathan Peyton30419822017-05-12 18:01:32 +0000883void __kmp_create_monitor(kmp_info_t *th) {
884 pthread_t handle;
885 pthread_attr_t thread_attr;
886 size_t size;
887 int status;
888 int auto_adj_size = FALSE;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000889
Jonathan Peyton30419822017-05-12 18:01:32 +0000890 if (__kmp_dflt_blocktime == KMP_MAX_BLOCKTIME) {
891 // We don't need monitor thread in case of MAX_BLOCKTIME
892 KA_TRACE(10, ("__kmp_create_monitor: skipping monitor thread because of "
893 "MAX blocktime\n"));
894 th->th.th_info.ds.ds_tid = 0; // this makes reap_monitor no-op
895 th->th.th_info.ds.ds_gtid = 0;
896 return;
897 }
898 KA_TRACE(10, ("__kmp_create_monitor: try to create monitor\n"));
899
900 KMP_MB(); /* Flush all pending memory write invalidates. */
901
902 th->th.th_info.ds.ds_tid = KMP_GTID_MONITOR;
903 th->th.th_info.ds.ds_gtid = KMP_GTID_MONITOR;
904#if KMP_REAL_TIME_FIX
905 TCW_4(__kmp_global.g.g_time.dt.t_value,
906 -1); // Will use it for synchronization a bit later.
907#else
908 TCW_4(__kmp_global.g.g_time.dt.t_value, 0);
909#endif // KMP_REAL_TIME_FIX
910
911#ifdef KMP_THREAD_ATTR
912 if (__kmp_monitor_stksize == 0) {
913 __kmp_monitor_stksize = KMP_DEFAULT_MONITOR_STKSIZE;
914 auto_adj_size = TRUE;
915 }
916 status = pthread_attr_init(&thread_attr);
917 if (status != 0) {
Jonathan Peyton6a393f72017-09-05 15:43:58 +0000918 __kmp_fatal(KMP_MSG(CantInitThreadAttrs), KMP_ERR(status), __kmp_msg_null);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +0000919 }
Jonathan Peyton30419822017-05-12 18:01:32 +0000920 status = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE);
921 if (status != 0) {
Jonathan Peyton6a393f72017-09-05 15:43:58 +0000922 __kmp_fatal(KMP_MSG(CantSetMonitorState), KMP_ERR(status), __kmp_msg_null);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +0000923 }
Jonathan Peyton30419822017-05-12 18:01:32 +0000924
925#ifdef _POSIX_THREAD_ATTR_STACKSIZE
926 status = pthread_attr_getstacksize(&thread_attr, &size);
927 KMP_CHECK_SYSFAIL("pthread_attr_getstacksize", status);
928#else
929 size = __kmp_sys_min_stksize;
930#endif /* _POSIX_THREAD_ATTR_STACKSIZE */
931#endif /* KMP_THREAD_ATTR */
932
933 if (__kmp_monitor_stksize == 0) {
934 __kmp_monitor_stksize = KMP_DEFAULT_MONITOR_STKSIZE;
935 }
936 if (__kmp_monitor_stksize < __kmp_sys_min_stksize) {
937 __kmp_monitor_stksize = __kmp_sys_min_stksize;
938 }
939
940 KA_TRACE(10, ("__kmp_create_monitor: default stacksize = %lu bytes,"
941 "requested stacksize = %lu bytes\n",
942 size, __kmp_monitor_stksize));
943
944retry:
945
946/* Set stack size for this thread now. */
947#ifdef _POSIX_THREAD_ATTR_STACKSIZE
948 KA_TRACE(10, ("__kmp_create_monitor: setting stacksize = %lu bytes,",
949 __kmp_monitor_stksize));
950 status = pthread_attr_setstacksize(&thread_attr, __kmp_monitor_stksize);
951 if (status != 0) {
952 if (auto_adj_size) {
953 __kmp_monitor_stksize *= 2;
954 goto retry;
Jonathan Peyton4fee5f62015-12-18 23:20:36 +0000955 }
Jonathan Peyton30419822017-05-12 18:01:32 +0000956 kmp_msg_t err_code = KMP_ERR(status);
957 __kmp_msg(kmp_ms_warning, // should this be fatal? BB
958 KMP_MSG(CantSetMonitorStackSize, (long int)__kmp_monitor_stksize),
959 err_code, KMP_HNT(ChangeMonitorStackSize), __kmp_msg_null);
960 if (__kmp_generate_warnings == kmp_warnings_off) {
961 __kmp_str_free(&err_code.str);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000962 }
Jonathan Peytonbd3a7632017-09-27 20:36:27 +0000963 }
Jonathan Peyton30419822017-05-12 18:01:32 +0000964#endif /* _POSIX_THREAD_ATTR_STACKSIZE */
Jim Cownie5e8470a2013-09-27 10:38:44 +0000965
Jonathan Peyton30419822017-05-12 18:01:32 +0000966 status =
967 pthread_create(&handle, &thread_attr, __kmp_launch_monitor, (void *)th);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000968
Jonathan Peyton30419822017-05-12 18:01:32 +0000969 if (status != 0) {
970#ifdef _POSIX_THREAD_ATTR_STACKSIZE
971 if (status == EINVAL) {
972 if (auto_adj_size && (__kmp_monitor_stksize < (size_t)0x40000000)) {
973 __kmp_monitor_stksize *= 2;
974 goto retry;
975 }
Jonathan Peyton6a393f72017-09-05 15:43:58 +0000976 __kmp_fatal(KMP_MSG(CantSetMonitorStackSize, __kmp_monitor_stksize),
977 KMP_ERR(status), KMP_HNT(IncreaseMonitorStackSize),
978 __kmp_msg_null);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +0000979 }
Jonathan Peyton30419822017-05-12 18:01:32 +0000980 if (status == ENOMEM) {
Jonathan Peyton6a393f72017-09-05 15:43:58 +0000981 __kmp_fatal(KMP_MSG(CantSetMonitorStackSize, __kmp_monitor_stksize),
982 KMP_ERR(status), KMP_HNT(DecreaseMonitorStackSize),
983 __kmp_msg_null);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +0000984 }
Jonathan Peyton30419822017-05-12 18:01:32 +0000985#endif /* _POSIX_THREAD_ATTR_STACKSIZE */
986 if (status == EAGAIN) {
Jonathan Peyton6a393f72017-09-05 15:43:58 +0000987 __kmp_fatal(KMP_MSG(NoResourcesForMonitorThread), KMP_ERR(status),
988 KMP_HNT(DecreaseNumberOfThreadsInUse), __kmp_msg_null);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +0000989 }
Jonathan Peyton30419822017-05-12 18:01:32 +0000990 KMP_SYSFAIL("pthread_create", status);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +0000991 }
Jim Cownie5e8470a2013-09-27 10:38:44 +0000992
Jonathan Peyton30419822017-05-12 18:01:32 +0000993 th->th.th_info.ds.ds_thread = handle;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000994
Jonathan Peyton30419822017-05-12 18:01:32 +0000995#if KMP_REAL_TIME_FIX
996 // Wait for the monitor thread is really started and set its *priority*.
997 KMP_DEBUG_ASSERT(sizeof(kmp_uint32) ==
998 sizeof(__kmp_global.g.g_time.dt.t_value));
Jonathan Peytone47d32f2019-02-28 19:11:29 +0000999 __kmp_wait_4((kmp_uint32 volatile *)&__kmp_global.g.g_time.dt.t_value, -1,
1000 &__kmp_neq_4, NULL);
Jonathan Peyton30419822017-05-12 18:01:32 +00001001#endif // KMP_REAL_TIME_FIX
Jim Cownie5e8470a2013-09-27 10:38:44 +00001002
Jonathan Peyton30419822017-05-12 18:01:32 +00001003#ifdef KMP_THREAD_ATTR
1004 status = pthread_attr_destroy(&thread_attr);
1005 if (status != 0) {
1006 kmp_msg_t err_code = KMP_ERR(status);
1007 __kmp_msg(kmp_ms_warning, KMP_MSG(CantDestroyThreadAttrs), err_code,
1008 __kmp_msg_null);
1009 if (__kmp_generate_warnings == kmp_warnings_off) {
1010 __kmp_str_free(&err_code.str);
1011 }
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00001012 }
Jonathan Peyton30419822017-05-12 18:01:32 +00001013#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +00001014
Jonathan Peyton30419822017-05-12 18:01:32 +00001015 KMP_MB(); /* Flush all pending memory write invalidates. */
Jim Cownie5e8470a2013-09-27 10:38:44 +00001016
Jonathan Peyton30419822017-05-12 18:01:32 +00001017 KA_TRACE(10, ("__kmp_create_monitor: monitor created %#.8lx\n",
1018 th->th.th_info.ds.ds_thread));
Jim Cownie5e8470a2013-09-27 10:38:44 +00001019
1020} // __kmp_create_monitor
Jonathan Peytonb66d1aa2016-09-27 17:11:17 +00001021#endif // KMP_USE_MONITOR
Jim Cownie5e8470a2013-09-27 10:38:44 +00001022
Jonathan Peyton30419822017-05-12 18:01:32 +00001023void __kmp_exit_thread(int exit_status) {
1024 pthread_exit((void *)(intptr_t)exit_status);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001025} // __kmp_exit_thread
1026
Jonathan Peytonb66d1aa2016-09-27 17:11:17 +00001027#if KMP_USE_MONITOR
Jim Cownie07ea89f2014-09-03 11:10:54 +00001028void __kmp_resume_monitor();
1029
Jonathan Peyton30419822017-05-12 18:01:32 +00001030void __kmp_reap_monitor(kmp_info_t *th) {
1031 int status;
1032 void *exit_val;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001033
Jonathan Peyton30419822017-05-12 18:01:32 +00001034 KA_TRACE(10, ("__kmp_reap_monitor: try to reap monitor thread with handle"
1035 " %#.8lx\n",
1036 th->th.th_info.ds.ds_thread));
Jim Cownie5e8470a2013-09-27 10:38:44 +00001037
Jonathan Peyton30419822017-05-12 18:01:32 +00001038 // If monitor has been created, its tid and gtid should be KMP_GTID_MONITOR.
1039 // If both tid and gtid are 0, it means the monitor did not ever start.
1040 // If both tid and gtid are KMP_GTID_DNE, the monitor has been shut down.
1041 KMP_DEBUG_ASSERT(th->th.th_info.ds.ds_tid == th->th.th_info.ds.ds_gtid);
1042 if (th->th.th_info.ds.ds_gtid != KMP_GTID_MONITOR) {
1043 KA_TRACE(10, ("__kmp_reap_monitor: monitor did not start, returning\n"));
1044 return;
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00001045 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00001046
Jonathan Peyton30419822017-05-12 18:01:32 +00001047 KMP_MB(); /* Flush all pending memory write invalidates. */
Jim Cownie5e8470a2013-09-27 10:38:44 +00001048
Jonathan Peyton30419822017-05-12 18:01:32 +00001049 /* First, check to see whether the monitor thread exists to wake it up. This
1050 is to avoid performance problem when the monitor sleeps during
1051 blocktime-size interval */
Jim Cownie5e8470a2013-09-27 10:38:44 +00001052
Jonathan Peyton30419822017-05-12 18:01:32 +00001053 status = pthread_kill(th->th.th_info.ds.ds_thread, 0);
1054 if (status != ESRCH) {
1055 __kmp_resume_monitor(); // Wake up the monitor thread
1056 }
1057 KA_TRACE(10, ("__kmp_reap_monitor: try to join with monitor\n"));
1058 status = pthread_join(th->th.th_info.ds.ds_thread, &exit_val);
1059 if (exit_val != th) {
Jonathan Peyton6a393f72017-09-05 15:43:58 +00001060 __kmp_fatal(KMP_MSG(ReapMonitorError), KMP_ERR(status), __kmp_msg_null);
Jonathan Peyton30419822017-05-12 18:01:32 +00001061 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00001062
Jonathan Peyton30419822017-05-12 18:01:32 +00001063 th->th.th_info.ds.ds_tid = KMP_GTID_DNE;
1064 th->th.th_info.ds.ds_gtid = KMP_GTID_DNE;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001065
Jonathan Peyton30419822017-05-12 18:01:32 +00001066 KA_TRACE(10, ("__kmp_reap_monitor: done reaping monitor thread with handle"
1067 " %#.8lx\n",
1068 th->th.th_info.ds.ds_thread));
Jim Cownie5e8470a2013-09-27 10:38:44 +00001069
Jonathan Peyton30419822017-05-12 18:01:32 +00001070 KMP_MB(); /* Flush all pending memory write invalidates. */
Jim Cownie5e8470a2013-09-27 10:38:44 +00001071}
Jonathan Peytonb66d1aa2016-09-27 17:11:17 +00001072#endif // KMP_USE_MONITOR
Jim Cownie5e8470a2013-09-27 10:38:44 +00001073
Jonathan Peyton30419822017-05-12 18:01:32 +00001074void __kmp_reap_worker(kmp_info_t *th) {
1075 int status;
1076 void *exit_val;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001077
Jonathan Peyton30419822017-05-12 18:01:32 +00001078 KMP_MB(); /* Flush all pending memory write invalidates. */
Jim Cownie5e8470a2013-09-27 10:38:44 +00001079
Jonathan Peyton30419822017-05-12 18:01:32 +00001080 KA_TRACE(
1081 10, ("__kmp_reap_worker: try to reap T#%d\n", th->th.th_info.ds.ds_gtid));
Jim Cownie5e8470a2013-09-27 10:38:44 +00001082
Jonathan Peyton30419822017-05-12 18:01:32 +00001083 status = pthread_join(th->th.th_info.ds.ds_thread, &exit_val);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001084#ifdef KMP_DEBUG
Jonathan Peyton30419822017-05-12 18:01:32 +00001085 /* Don't expose these to the user until we understand when they trigger */
1086 if (status != 0) {
Jonathan Peyton6a393f72017-09-05 15:43:58 +00001087 __kmp_fatal(KMP_MSG(ReapWorkerError), KMP_ERR(status), __kmp_msg_null);
Jonathan Peyton30419822017-05-12 18:01:32 +00001088 }
1089 if (exit_val != th) {
1090 KA_TRACE(10, ("__kmp_reap_worker: worker T#%d did not reap properly, "
1091 "exit_val = %p\n",
1092 th->th.th_info.ds.ds_gtid, exit_val));
1093 }
Jonathan Peyton93495de2016-06-13 17:36:40 +00001094#endif /* KMP_DEBUG */
Jim Cownie5e8470a2013-09-27 10:38:44 +00001095
Jonathan Peyton30419822017-05-12 18:01:32 +00001096 KA_TRACE(10, ("__kmp_reap_worker: done reaping T#%d\n",
1097 th->th.th_info.ds.ds_gtid));
Jim Cownie5e8470a2013-09-27 10:38:44 +00001098
Jonathan Peyton30419822017-05-12 18:01:32 +00001099 KMP_MB(); /* Flush all pending memory write invalidates. */
Jim Cownie5e8470a2013-09-27 10:38:44 +00001100}
1101
Jim Cownie5e8470a2013-09-27 10:38:44 +00001102#if KMP_HANDLE_SIGNALS
1103
Jonathan Peyton30419822017-05-12 18:01:32 +00001104static void __kmp_null_handler(int signo) {
1105 // Do nothing, for doing SIG_IGN-type actions.
Jim Cownie5e8470a2013-09-27 10:38:44 +00001106} // __kmp_null_handler
1107
Jonathan Peyton30419822017-05-12 18:01:32 +00001108static void __kmp_team_handler(int signo) {
1109 if (__kmp_global.g.g_abort == 0) {
1110/* Stage 1 signal handler, let's shut down all of the threads */
1111#ifdef KMP_DEBUG
1112 __kmp_debug_printf("__kmp_team_handler: caught signal = %d\n", signo);
1113#endif
1114 switch (signo) {
1115 case SIGHUP:
1116 case SIGINT:
1117 case SIGQUIT:
1118 case SIGILL:
1119 case SIGABRT:
1120 case SIGFPE:
1121 case SIGBUS:
1122 case SIGSEGV:
1123#ifdef SIGSYS
1124 case SIGSYS:
1125#endif
1126 case SIGTERM:
1127 if (__kmp_debug_buf) {
1128 __kmp_dump_debug_buffer();
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00001129 }
Jonathan Peyton30419822017-05-12 18:01:32 +00001130 KMP_MB(); // Flush all pending memory write invalidates.
1131 TCW_4(__kmp_global.g.g_abort, signo);
1132 KMP_MB(); // Flush all pending memory write invalidates.
1133 TCW_4(__kmp_global.g.g_done, TRUE);
1134 KMP_MB(); // Flush all pending memory write invalidates.
1135 break;
1136 default:
1137#ifdef KMP_DEBUG
1138 __kmp_debug_printf("__kmp_team_handler: unknown signal type");
1139#endif
1140 break;
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00001141 }
1142 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00001143} // __kmp_team_handler
1144
Jonathan Peyton30419822017-05-12 18:01:32 +00001145static void __kmp_sigaction(int signum, const struct sigaction *act,
1146 struct sigaction *oldact) {
1147 int rc = sigaction(signum, act, oldact);
1148 KMP_CHECK_SYSFAIL_ERRNO("sigaction", rc);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001149}
1150
Jonathan Peyton30419822017-05-12 18:01:32 +00001151static void __kmp_install_one_handler(int sig, sig_func_t handler_func,
1152 int parallel_init) {
1153 KMP_MB(); // Flush all pending memory write invalidates.
1154 KB_TRACE(60,
1155 ("__kmp_install_one_handler( %d, ..., %d )\n", sig, parallel_init));
1156 if (parallel_init) {
1157 struct sigaction new_action;
1158 struct sigaction old_action;
1159 new_action.sa_handler = handler_func;
1160 new_action.sa_flags = 0;
1161 sigfillset(&new_action.sa_mask);
1162 __kmp_sigaction(sig, &new_action, &old_action);
1163 if (old_action.sa_handler == __kmp_sighldrs[sig].sa_handler) {
1164 sigaddset(&__kmp_sigset, sig);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001165 } else {
Jonathan Peyton30419822017-05-12 18:01:32 +00001166 // Restore/keep user's handler if one previously installed.
1167 __kmp_sigaction(sig, &old_action, NULL);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00001168 }
Jonathan Peyton30419822017-05-12 18:01:32 +00001169 } else {
1170 // Save initial/system signal handlers to see if user handlers installed.
1171 __kmp_sigaction(sig, NULL, &__kmp_sighldrs[sig]);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00001172 }
Jonathan Peyton30419822017-05-12 18:01:32 +00001173 KMP_MB(); // Flush all pending memory write invalidates.
Jim Cownie5e8470a2013-09-27 10:38:44 +00001174} // __kmp_install_one_handler
1175
Jonathan Peyton30419822017-05-12 18:01:32 +00001176static void __kmp_remove_one_handler(int sig) {
1177 KB_TRACE(60, ("__kmp_remove_one_handler( %d )\n", sig));
1178 if (sigismember(&__kmp_sigset, sig)) {
1179 struct sigaction old;
1180 KMP_MB(); // Flush all pending memory write invalidates.
1181 __kmp_sigaction(sig, &__kmp_sighldrs[sig], &old);
1182 if ((old.sa_handler != __kmp_team_handler) &&
1183 (old.sa_handler != __kmp_null_handler)) {
1184 // Restore the users signal handler.
1185 KB_TRACE(10, ("__kmp_remove_one_handler: oops, not our handler, "
1186 "restoring: sig=%d\n",
1187 sig));
1188 __kmp_sigaction(sig, &old, NULL);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00001189 }
Jonathan Peyton30419822017-05-12 18:01:32 +00001190 sigdelset(&__kmp_sigset, sig);
1191 KMP_MB(); // Flush all pending memory write invalidates.
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00001192 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00001193} // __kmp_remove_one_handler
1194
Jonathan Peyton30419822017-05-12 18:01:32 +00001195void __kmp_install_signals(int parallel_init) {
1196 KB_TRACE(10, ("__kmp_install_signals( %d )\n", parallel_init));
1197 if (__kmp_handle_signals || !parallel_init) {
1198 // If ! parallel_init, we do not install handlers, just save original
1199 // handlers. Let us do it even __handle_signals is 0.
1200 sigemptyset(&__kmp_sigset);
1201 __kmp_install_one_handler(SIGHUP, __kmp_team_handler, parallel_init);
1202 __kmp_install_one_handler(SIGINT, __kmp_team_handler, parallel_init);
1203 __kmp_install_one_handler(SIGQUIT, __kmp_team_handler, parallel_init);
1204 __kmp_install_one_handler(SIGILL, __kmp_team_handler, parallel_init);
1205 __kmp_install_one_handler(SIGABRT, __kmp_team_handler, parallel_init);
1206 __kmp_install_one_handler(SIGFPE, __kmp_team_handler, parallel_init);
1207 __kmp_install_one_handler(SIGBUS, __kmp_team_handler, parallel_init);
1208 __kmp_install_one_handler(SIGSEGV, __kmp_team_handler, parallel_init);
1209#ifdef SIGSYS
1210 __kmp_install_one_handler(SIGSYS, __kmp_team_handler, parallel_init);
1211#endif // SIGSYS
1212 __kmp_install_one_handler(SIGTERM, __kmp_team_handler, parallel_init);
1213#ifdef SIGPIPE
1214 __kmp_install_one_handler(SIGPIPE, __kmp_team_handler, parallel_init);
1215#endif // SIGPIPE
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00001216 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00001217} // __kmp_install_signals
1218
Jonathan Peyton30419822017-05-12 18:01:32 +00001219void __kmp_remove_signals(void) {
1220 int sig;
1221 KB_TRACE(10, ("__kmp_remove_signals()\n"));
1222 for (sig = 1; sig < NSIG; ++sig) {
1223 __kmp_remove_one_handler(sig);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00001224 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00001225} // __kmp_remove_signals
1226
Jim Cownie5e8470a2013-09-27 10:38:44 +00001227#endif // KMP_HANDLE_SIGNALS
1228
Jonathan Peyton30419822017-05-12 18:01:32 +00001229void __kmp_enable(int new_state) {
1230#ifdef KMP_CANCEL_THREADS
1231 int status, old_state;
1232 status = pthread_setcancelstate(new_state, &old_state);
1233 KMP_CHECK_SYSFAIL("pthread_setcancelstate", status);
1234 KMP_DEBUG_ASSERT(old_state == PTHREAD_CANCEL_DISABLE);
1235#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +00001236}
1237
Jonathan Peyton30419822017-05-12 18:01:32 +00001238void __kmp_disable(int *old_state) {
1239#ifdef KMP_CANCEL_THREADS
1240 int status;
1241 status = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, old_state);
1242 KMP_CHECK_SYSFAIL("pthread_setcancelstate", status);
1243#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +00001244}
1245
Jonathan Peytoneaa9e402018-01-10 18:21:48 +00001246static void __kmp_atfork_prepare(void) {
1247 __kmp_acquire_bootstrap_lock(&__kmp_initz_lock);
1248 __kmp_acquire_bootstrap_lock(&__kmp_forkjoin_lock);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001249}
1250
Jonathan Peytoneaa9e402018-01-10 18:21:48 +00001251static void __kmp_atfork_parent(void) {
1252 __kmp_release_bootstrap_lock(&__kmp_initz_lock);
1253 __kmp_release_bootstrap_lock(&__kmp_forkjoin_lock);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001254}
1255
Jonathan Peyton30419822017-05-12 18:01:32 +00001256/* Reset the library so execution in the child starts "all over again" with
1257 clean data structures in initial states. Don't worry about freeing memory
1258 allocated by parent, just abandon it to be safe. */
1259static void __kmp_atfork_child(void) {
Jonathan Peytoneaa9e402018-01-10 18:21:48 +00001260 __kmp_release_bootstrap_lock(&__kmp_forkjoin_lock);
Jonathan Peyton30419822017-05-12 18:01:32 +00001261 /* TODO make sure this is done right for nested/sibling */
1262 // ATT: Memory leaks are here? TODO: Check it and fix.
1263 /* KMP_ASSERT( 0 ); */
Jim Cownie5e8470a2013-09-27 10:38:44 +00001264
Jonathan Peyton30419822017-05-12 18:01:32 +00001265 ++__kmp_fork_count;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001266
Jonathan Peyton072ccb72017-06-15 21:51:07 +00001267#if KMP_AFFINITY_SUPPORTED
1268#if KMP_OS_LINUX
Jonathan Peytond330e632017-06-13 17:16:12 +00001269 // reset the affinity in the child to the initial thread
1270 // affinity in the parent
1271 kmp_set_thread_affinity_mask_initial();
1272#endif
Jonathan Peyton072ccb72017-06-15 21:51:07 +00001273 // Set default not to bind threads tightly in the child (we’re expecting
1274 // over-subscription after the fork and this can improve things for
1275 // scripting languages that use OpenMP inside process-parallel code).
1276 __kmp_affinity_type = affinity_none;
Jonathan Peyton072ccb72017-06-15 21:51:07 +00001277 if (__kmp_nested_proc_bind.bind_types != NULL) {
1278 __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
1279 }
Jonathan Peyton072ccb72017-06-15 21:51:07 +00001280#endif // KMP_AFFINITY_SUPPORTED
Jonathan Peytond330e632017-06-13 17:16:12 +00001281
Jonathan Peyton30419822017-05-12 18:01:32 +00001282 __kmp_init_runtime = FALSE;
Jonathan Peytonb66d1aa2016-09-27 17:11:17 +00001283#if KMP_USE_MONITOR
Jonathan Peyton30419822017-05-12 18:01:32 +00001284 __kmp_init_monitor = 0;
Jonathan Peytonb66d1aa2016-09-27 17:11:17 +00001285#endif
Jonathan Peyton30419822017-05-12 18:01:32 +00001286 __kmp_init_parallel = FALSE;
1287 __kmp_init_middle = FALSE;
1288 __kmp_init_serial = FALSE;
1289 TCW_4(__kmp_init_gtid, FALSE);
1290 __kmp_init_common = FALSE;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001291
Jonathan Peyton30419822017-05-12 18:01:32 +00001292 TCW_4(__kmp_init_user_locks, FALSE);
1293#if !KMP_USE_DYNAMIC_LOCK
1294 __kmp_user_lock_table.used = 1;
1295 __kmp_user_lock_table.allocated = 0;
1296 __kmp_user_lock_table.table = NULL;
1297 __kmp_lock_blocks = NULL;
Andrey Churbanov5c56fb52015-02-20 18:05:17 +00001298#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +00001299
Jonathan Peyton30419822017-05-12 18:01:32 +00001300 __kmp_all_nth = 0;
1301 TCW_4(__kmp_nth, 0);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001302
Jonathan Peytoneaa9e402018-01-10 18:21:48 +00001303 __kmp_thread_pool = NULL;
1304 __kmp_thread_pool_insert_pt = NULL;
1305 __kmp_team_pool = NULL;
1306
Jonathan Peyton30419822017-05-12 18:01:32 +00001307 /* Must actually zero all the *cache arguments passed to __kmpc_threadprivate
1308 here so threadprivate doesn't use stale data */
1309 KA_TRACE(10, ("__kmp_atfork_child: checking cache address list %p\n",
1310 __kmp_threadpriv_cache_list));
Jim Cownie5e8470a2013-09-27 10:38:44 +00001311
Jonathan Peyton30419822017-05-12 18:01:32 +00001312 while (__kmp_threadpriv_cache_list != NULL) {
Jim Cownie5e8470a2013-09-27 10:38:44 +00001313
Jonathan Peyton30419822017-05-12 18:01:32 +00001314 if (*__kmp_threadpriv_cache_list->addr != NULL) {
1315 KC_TRACE(50, ("__kmp_atfork_child: zeroing cache at address %p\n",
1316 &(*__kmp_threadpriv_cache_list->addr)));
Jim Cownie5e8470a2013-09-27 10:38:44 +00001317
Jonathan Peyton30419822017-05-12 18:01:32 +00001318 *__kmp_threadpriv_cache_list->addr = NULL;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001319 }
Jonathan Peyton30419822017-05-12 18:01:32 +00001320 __kmp_threadpriv_cache_list = __kmp_threadpriv_cache_list->next;
1321 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00001322
Jonathan Peyton30419822017-05-12 18:01:32 +00001323 __kmp_init_runtime = FALSE;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001324
Jonathan Peyton30419822017-05-12 18:01:32 +00001325 /* reset statically initialized locks */
1326 __kmp_init_bootstrap_lock(&__kmp_initz_lock);
1327 __kmp_init_bootstrap_lock(&__kmp_stdio_lock);
1328 __kmp_init_bootstrap_lock(&__kmp_console_lock);
Jonathan Peytoneaa9e402018-01-10 18:21:48 +00001329 __kmp_init_bootstrap_lock(&__kmp_task_team_lock);
1330
Andrey Churbanov5388acd2018-01-11 15:09:49 +00001331#if USE_ITT_BUILD
Jonathan Peytoneaa9e402018-01-10 18:21:48 +00001332 __kmp_itt_reset(); // reset ITT's global state
Andrey Churbanov5388acd2018-01-11 15:09:49 +00001333#endif /* USE_ITT_BUILD */
Jim Cownie5e8470a2013-09-27 10:38:44 +00001334
Jonathan Peyton30419822017-05-12 18:01:32 +00001335 /* This is necessary to make sure no stale data is left around */
1336 /* AC: customers complain that we use unsafe routines in the atfork
1337 handler. Mathworks: dlsym() is unsafe. We call dlsym and dlopen
1338 in dynamic_link when check the presence of shared tbbmalloc library.
1339 Suggestion is to make the library initialization lazier, similar
1340 to what done for __kmpc_begin(). */
1341 // TODO: synchronize all static initializations with regular library
1342 // startup; look at kmp_global.cpp and etc.
1343 //__kmp_internal_begin ();
Jim Cownie5e8470a2013-09-27 10:38:44 +00001344}
1345
Jonathan Peyton30419822017-05-12 18:01:32 +00001346void __kmp_register_atfork(void) {
1347 if (__kmp_need_register_atfork) {
1348 int status = pthread_atfork(__kmp_atfork_prepare, __kmp_atfork_parent,
1349 __kmp_atfork_child);
1350 KMP_CHECK_SYSFAIL("pthread_atfork", status);
1351 __kmp_need_register_atfork = FALSE;
1352 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00001353}
1354
Jonathan Peyton30419822017-05-12 18:01:32 +00001355void __kmp_suspend_initialize(void) {
1356 int status;
1357 status = pthread_mutexattr_init(&__kmp_suspend_mutex_attr);
1358 KMP_CHECK_SYSFAIL("pthread_mutexattr_init", status);
1359 status = pthread_condattr_init(&__kmp_suspend_cond_attr);
1360 KMP_CHECK_SYSFAIL("pthread_condattr_init", status);
1361}
1362
Jonathan Peytonfeac33e2019-04-08 17:50:02 +00001363void __kmp_suspend_initialize_thread(kmp_info_t *th) {
Jonathan Peyton30419822017-05-12 18:01:32 +00001364 ANNOTATE_HAPPENS_AFTER(&th->th.th_suspend_init_count);
Andrey Churbanovf8f788b2019-05-16 17:52:53 +00001365 int old_value = KMP_ATOMIC_LD_RLX(&th->th.th_suspend_init_count);
1366 int new_value = __kmp_fork_count + 1;
1367 // Return if already initialized
1368 if (old_value == new_value)
1369 return;
1370 // Wait, then return if being initialized
1371 if (old_value == -1 ||
1372 !__kmp_atomic_compare_store(&th->th.th_suspend_init_count, old_value,
1373 -1)) {
1374 while (KMP_ATOMIC_LD_ACQ(&th->th.th_suspend_init_count) != new_value) {
1375 KMP_CPU_PAUSE();
1376 }
1377 } else {
1378 // Claim to be the initializer and do initializations
Jim Cownie5e8470a2013-09-27 10:38:44 +00001379 int status;
Jonathan Peyton30419822017-05-12 18:01:32 +00001380 status = pthread_cond_init(&th->th.th_suspend_cv.c_cond,
1381 &__kmp_suspend_cond_attr);
1382 KMP_CHECK_SYSFAIL("pthread_cond_init", status);
1383 status = pthread_mutex_init(&th->th.th_suspend_mx.m_mutex,
1384 &__kmp_suspend_mutex_attr);
1385 KMP_CHECK_SYSFAIL("pthread_mutex_init", status);
Andrey Churbanovf8f788b2019-05-16 17:52:53 +00001386 KMP_ATOMIC_ST_REL(&th->th.th_suspend_init_count, new_value);
Jonathan Peyton30419822017-05-12 18:01:32 +00001387 ANNOTATE_HAPPENS_BEFORE(&th->th.th_suspend_init_count);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00001388 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00001389}
1390
Jonathan Peyton30419822017-05-12 18:01:32 +00001391void __kmp_suspend_uninitialize_thread(kmp_info_t *th) {
Andrey Churbanovf8f788b2019-05-16 17:52:53 +00001392 if (KMP_ATOMIC_LD_ACQ(&th->th.th_suspend_init_count) > __kmp_fork_count) {
Jonathan Peyton30419822017-05-12 18:01:32 +00001393 /* this means we have initialize the suspension pthread objects for this
1394 thread in this instance of the process */
1395 int status;
1396
1397 status = pthread_cond_destroy(&th->th.th_suspend_cv.c_cond);
1398 if (status != 0 && status != EBUSY) {
1399 KMP_SYSFAIL("pthread_cond_destroy", status);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00001400 }
Jonathan Peyton30419822017-05-12 18:01:32 +00001401 status = pthread_mutex_destroy(&th->th.th_suspend_mx.m_mutex);
1402 if (status != 0 && status != EBUSY) {
1403 KMP_SYSFAIL("pthread_mutex_destroy", status);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00001404 }
Jonathan Peyton30419822017-05-12 18:01:32 +00001405 --th->th.th_suspend_init_count;
Andrey Churbanovf8f788b2019-05-16 17:52:53 +00001406 KMP_DEBUG_ASSERT(KMP_ATOMIC_LD_RLX(&th->th.th_suspend_init_count) ==
1407 __kmp_fork_count);
Jonathan Peyton30419822017-05-12 18:01:32 +00001408 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00001409}
1410
Jonathan Peyton9b8bb322019-01-16 20:07:39 +00001411// return true if lock obtained, false otherwise
1412int __kmp_try_suspend_mx(kmp_info_t *th) {
1413 return (pthread_mutex_trylock(&th->th.th_suspend_mx.m_mutex) == 0);
1414}
1415
1416void __kmp_lock_suspend_mx(kmp_info_t *th) {
1417 int status = pthread_mutex_lock(&th->th.th_suspend_mx.m_mutex);
1418 KMP_CHECK_SYSFAIL("pthread_mutex_lock", status);
1419}
1420
1421void __kmp_unlock_suspend_mx(kmp_info_t *th) {
1422 int status = pthread_mutex_unlock(&th->th.th_suspend_mx.m_mutex);
1423 KMP_CHECK_SYSFAIL("pthread_mutex_unlock", status);
1424}
1425
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001426/* This routine puts the calling thread to sleep after setting the
Jonathan Peyton30419822017-05-12 18:01:32 +00001427 sleep bit for the indicated flag variable to true. */
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001428template <class C>
Jonathan Peyton30419822017-05-12 18:01:32 +00001429static inline void __kmp_suspend_template(int th_gtid, C *flag) {
1430 KMP_TIME_DEVELOPER_PARTITIONED_BLOCK(USER_suspend);
1431 kmp_info_t *th = __kmp_threads[th_gtid];
1432 int status;
1433 typename C::flag_t old_spin;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001434
Jonathan Peyton30419822017-05-12 18:01:32 +00001435 KF_TRACE(30, ("__kmp_suspend_template: T#%d enter for flag = %p\n", th_gtid,
1436 flag->get()));
Jim Cownie5e8470a2013-09-27 10:38:44 +00001437
Jonathan Peyton30419822017-05-12 18:01:32 +00001438 __kmp_suspend_initialize_thread(th);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001439
Jonathan Peyton30419822017-05-12 18:01:32 +00001440 status = pthread_mutex_lock(&th->th.th_suspend_mx.m_mutex);
1441 KMP_CHECK_SYSFAIL("pthread_mutex_lock", status);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001442
Jonathan Peyton30419822017-05-12 18:01:32 +00001443 KF_TRACE(10, ("__kmp_suspend_template: T#%d setting sleep bit for spin(%p)\n",
1444 th_gtid, flag->get()));
Jim Cownie5e8470a2013-09-27 10:38:44 +00001445
Jonathan Peyton30419822017-05-12 18:01:32 +00001446 /* TODO: shouldn't this use release semantics to ensure that
1447 __kmp_suspend_initialize_thread gets called first? */
1448 old_spin = flag->set_sleeping();
Jonathan Peyton9b8bb322019-01-16 20:07:39 +00001449 if (__kmp_dflt_blocktime == KMP_MAX_BLOCKTIME &&
1450 __kmp_pause_status != kmp_soft_paused) {
1451 flag->unset_sleeping();
1452 status = pthread_mutex_unlock(&th->th.th_suspend_mx.m_mutex);
1453 KMP_CHECK_SYSFAIL("pthread_mutex_unlock", status);
1454 return;
1455 }
Jonathan Peyton30419822017-05-12 18:01:32 +00001456 KF_TRACE(5, ("__kmp_suspend_template: T#%d set sleep bit for spin(%p)==%x,"
1457 " was %x\n",
Jonathan Peyton37e2ef52018-07-09 17:36:22 +00001458 th_gtid, flag->get(), flag->load(), old_spin));
Jim Cownie5e8470a2013-09-27 10:38:44 +00001459
Jonathan Peyton30419822017-05-12 18:01:32 +00001460 if (flag->done_check_val(old_spin)) {
1461 old_spin = flag->unset_sleeping();
1462 KF_TRACE(5, ("__kmp_suspend_template: T#%d false alarm, reset sleep bit "
1463 "for spin(%p)\n",
1464 th_gtid, flag->get()));
1465 } else {
1466 /* Encapsulate in a loop as the documentation states that this may
1467 "with low probability" return when the condition variable has
1468 not been signaled or broadcast */
1469 int deactivated = FALSE;
1470 TCW_PTR(th->th.th_sleep_loc, (void *)flag);
1471
1472 while (flag->is_sleeping()) {
Jim Cownie5e8470a2013-09-27 10:38:44 +00001473#ifdef DEBUG_SUSPEND
Jonathan Peyton30419822017-05-12 18:01:32 +00001474 char buffer[128];
1475 __kmp_suspend_count++;
1476 __kmp_print_cond(buffer, &th->th.th_suspend_cv);
1477 __kmp_printf("__kmp_suspend_template: suspending T#%d: %s\n", th_gtid,
1478 buffer);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001479#endif
Jonathan Peyton30419822017-05-12 18:01:32 +00001480 // Mark the thread as no longer active (only in the first iteration of the
1481 // loop).
1482 if (!deactivated) {
1483 th->th.th_active = FALSE;
1484 if (th->th.th_active_in_pool) {
1485 th->th.th_active_in_pool = FALSE;
Jonathan Peyton37e2ef52018-07-09 17:36:22 +00001486 KMP_ATOMIC_DEC(&__kmp_thread_pool_active_nth);
Jonathan Peyton30419822017-05-12 18:01:32 +00001487 KMP_DEBUG_ASSERT(TCR_4(__kmp_thread_pool_active_nth) >= 0);
1488 }
1489 deactivated = TRUE;
1490 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00001491
1492#if USE_SUSPEND_TIMEOUT
Jonathan Peyton30419822017-05-12 18:01:32 +00001493 struct timespec now;
1494 struct timeval tval;
1495 int msecs;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001496
Jonathan Peyton30419822017-05-12 18:01:32 +00001497 status = gettimeofday(&tval, NULL);
1498 KMP_CHECK_SYSFAIL_ERRNO("gettimeofday", status);
1499 TIMEVAL_TO_TIMESPEC(&tval, &now);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001500
Jonathan Peyton30419822017-05-12 18:01:32 +00001501 msecs = (4 * __kmp_dflt_blocktime) + 200;
1502 now.tv_sec += msecs / 1000;
1503 now.tv_nsec += (msecs % 1000) * 1000;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001504
Jonathan Peyton30419822017-05-12 18:01:32 +00001505 KF_TRACE(15, ("__kmp_suspend_template: T#%d about to perform "
1506 "pthread_cond_timedwait\n",
1507 th_gtid));
1508 status = pthread_cond_timedwait(&th->th.th_suspend_cv.c_cond,
1509 &th->th.th_suspend_mx.m_mutex, &now);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001510#else
Jonathan Peyton30419822017-05-12 18:01:32 +00001511 KF_TRACE(15, ("__kmp_suspend_template: T#%d about to perform"
1512 " pthread_cond_wait\n",
1513 th_gtid));
1514 status = pthread_cond_wait(&th->th.th_suspend_cv.c_cond,
1515 &th->th.th_suspend_mx.m_mutex);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001516#endif
1517
Jonathan Peyton30419822017-05-12 18:01:32 +00001518 if ((status != 0) && (status != EINTR) && (status != ETIMEDOUT)) {
1519 KMP_SYSFAIL("pthread_cond_wait", status);
1520 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00001521#ifdef KMP_DEBUG
Jonathan Peyton30419822017-05-12 18:01:32 +00001522 if (status == ETIMEDOUT) {
1523 if (flag->is_sleeping()) {
1524 KF_TRACE(100,
1525 ("__kmp_suspend_template: T#%d timeout wakeup\n", th_gtid));
1526 } else {
1527 KF_TRACE(2, ("__kmp_suspend_template: T#%d timeout wakeup, sleep bit "
1528 "not set!\n",
1529 th_gtid));
Jim Cownie5e8470a2013-09-27 10:38:44 +00001530 }
Jonathan Peyton30419822017-05-12 18:01:32 +00001531 } else if (flag->is_sleeping()) {
1532 KF_TRACE(100,
1533 ("__kmp_suspend_template: T#%d spurious wakeup\n", th_gtid));
1534 }
1535#endif
1536 } // while
Jim Cownie5e8470a2013-09-27 10:38:44 +00001537
Jonathan Peyton30419822017-05-12 18:01:32 +00001538 // Mark the thread as active again (if it was previous marked as inactive)
1539 if (deactivated) {
1540 th->th.th_active = TRUE;
1541 if (TCR_4(th->th.th_in_pool)) {
Jonathan Peyton37e2ef52018-07-09 17:36:22 +00001542 KMP_ATOMIC_INC(&__kmp_thread_pool_active_nth);
Jonathan Peyton30419822017-05-12 18:01:32 +00001543 th->th.th_active_in_pool = TRUE;
1544 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00001545 }
Jonathan Peyton30419822017-05-12 18:01:32 +00001546 }
1547#ifdef DEBUG_SUSPEND
1548 {
1549 char buffer[128];
1550 __kmp_print_cond(buffer, &th->th.th_suspend_cv);
1551 __kmp_printf("__kmp_suspend_template: T#%d has awakened: %s\n", th_gtid,
1552 buffer);
1553 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00001554#endif
1555
Jonathan Peyton30419822017-05-12 18:01:32 +00001556 status = pthread_mutex_unlock(&th->th.th_suspend_mx.m_mutex);
1557 KMP_CHECK_SYSFAIL("pthread_mutex_unlock", status);
1558 KF_TRACE(30, ("__kmp_suspend_template: T#%d exit\n", th_gtid));
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001559}
1560
1561void __kmp_suspend_32(int th_gtid, kmp_flag_32 *flag) {
Jonathan Peyton30419822017-05-12 18:01:32 +00001562 __kmp_suspend_template(th_gtid, flag);
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001563}
1564void __kmp_suspend_64(int th_gtid, kmp_flag_64 *flag) {
Jonathan Peyton30419822017-05-12 18:01:32 +00001565 __kmp_suspend_template(th_gtid, flag);
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001566}
1567void __kmp_suspend_oncore(int th_gtid, kmp_flag_oncore *flag) {
Jonathan Peyton30419822017-05-12 18:01:32 +00001568 __kmp_suspend_template(th_gtid, flag);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001569}
1570
Jim Cownie5e8470a2013-09-27 10:38:44 +00001571/* This routine signals the thread specified by target_gtid to wake up
Jonathan Peyton30419822017-05-12 18:01:32 +00001572 after setting the sleep bit indicated by the flag argument to FALSE.
1573 The target thread must already have called __kmp_suspend_template() */
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001574template <class C>
Jonathan Peyton30419822017-05-12 18:01:32 +00001575static inline void __kmp_resume_template(int target_gtid, C *flag) {
1576 KMP_TIME_DEVELOPER_PARTITIONED_BLOCK(USER_resume);
1577 kmp_info_t *th = __kmp_threads[target_gtid];
1578 int status;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001579
1580#ifdef KMP_DEBUG
Jonathan Peyton30419822017-05-12 18:01:32 +00001581 int gtid = TCR_4(__kmp_init_gtid) ? __kmp_get_gtid() : -1;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001582#endif
1583
Jonathan Peyton30419822017-05-12 18:01:32 +00001584 KF_TRACE(30, ("__kmp_resume_template: T#%d wants to wakeup T#%d enter\n",
1585 gtid, target_gtid));
1586 KMP_DEBUG_ASSERT(gtid != target_gtid);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001587
Jonathan Peyton30419822017-05-12 18:01:32 +00001588 __kmp_suspend_initialize_thread(th);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001589
Jonathan Peyton30419822017-05-12 18:01:32 +00001590 status = pthread_mutex_lock(&th->th.th_suspend_mx.m_mutex);
1591 KMP_CHECK_SYSFAIL("pthread_mutex_lock", status);
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001592
Jonathan Peyton30419822017-05-12 18:01:32 +00001593 if (!flag) { // coming from __kmp_null_resume_wrapper
Andrey Churbanovc47afcd2017-07-03 11:24:08 +00001594 flag = (C *)CCAST(void *, th->th.th_sleep_loc);
Jonathan Peyton30419822017-05-12 18:01:32 +00001595 }
1596
1597 // First, check if the flag is null or its type has changed. If so, someone
1598 // else woke it up.
1599 if (!flag || flag->get_type() != flag->get_ptr_type()) { // get_ptr_type
1600 // simply shows what
1601 // flag was cast to
1602 KF_TRACE(5, ("__kmp_resume_template: T#%d exiting, thread T#%d already "
1603 "awake: flag(%p)\n",
1604 gtid, target_gtid, NULL));
1605 status = pthread_mutex_unlock(&th->th.th_suspend_mx.m_mutex);
1606 KMP_CHECK_SYSFAIL("pthread_mutex_unlock", status);
1607 return;
1608 } else { // if multiple threads are sleeping, flag should be internally
1609 // referring to a specific thread here
1610 typename C::flag_t old_spin = flag->unset_sleeping();
1611 if (!flag->is_sleeping_val(old_spin)) {
1612 KF_TRACE(5, ("__kmp_resume_template: T#%d exiting, thread T#%d already "
1613 "awake: flag(%p): "
1614 "%u => %u\n",
Jonathan Peyton37e2ef52018-07-09 17:36:22 +00001615 gtid, target_gtid, flag->get(), old_spin, flag->load()));
Jonathan Peyton30419822017-05-12 18:01:32 +00001616 status = pthread_mutex_unlock(&th->th.th_suspend_mx.m_mutex);
1617 KMP_CHECK_SYSFAIL("pthread_mutex_unlock", status);
1618 return;
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001619 }
Jonathan Peyton30419822017-05-12 18:01:32 +00001620 KF_TRACE(5, ("__kmp_resume_template: T#%d about to wakeup T#%d, reset "
1621 "sleep bit for flag's loc(%p): "
1622 "%u => %u\n",
Jonathan Peyton37e2ef52018-07-09 17:36:22 +00001623 gtid, target_gtid, flag->get(), old_spin, flag->load()));
Jonathan Peyton30419822017-05-12 18:01:32 +00001624 }
1625 TCW_PTR(th->th.th_sleep_loc, NULL);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001626
1627#ifdef DEBUG_SUSPEND
Jonathan Peyton30419822017-05-12 18:01:32 +00001628 {
1629 char buffer[128];
1630 __kmp_print_cond(buffer, &th->th.th_suspend_cv);
1631 __kmp_printf("__kmp_resume_template: T#%d resuming T#%d: %s\n", gtid,
1632 target_gtid, buffer);
1633 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00001634#endif
Jonathan Peyton30419822017-05-12 18:01:32 +00001635 status = pthread_cond_signal(&th->th.th_suspend_cv.c_cond);
1636 KMP_CHECK_SYSFAIL("pthread_cond_signal", status);
1637 status = pthread_mutex_unlock(&th->th.th_suspend_mx.m_mutex);
1638 KMP_CHECK_SYSFAIL("pthread_mutex_unlock", status);
1639 KF_TRACE(30, ("__kmp_resume_template: T#%d exiting after signaling wake up"
1640 " for T#%d\n",
1641 gtid, target_gtid));
Jim Cownie5e8470a2013-09-27 10:38:44 +00001642}
1643
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001644void __kmp_resume_32(int target_gtid, kmp_flag_32 *flag) {
Jonathan Peyton30419822017-05-12 18:01:32 +00001645 __kmp_resume_template(target_gtid, flag);
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001646}
1647void __kmp_resume_64(int target_gtid, kmp_flag_64 *flag) {
Jonathan Peyton30419822017-05-12 18:01:32 +00001648 __kmp_resume_template(target_gtid, flag);
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001649}
1650void __kmp_resume_oncore(int target_gtid, kmp_flag_oncore *flag) {
Jonathan Peyton30419822017-05-12 18:01:32 +00001651 __kmp_resume_template(target_gtid, flag);
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001652}
1653
Jonathan Peytonb66d1aa2016-09-27 17:11:17 +00001654#if KMP_USE_MONITOR
Jonathan Peyton30419822017-05-12 18:01:32 +00001655void __kmp_resume_monitor() {
1656 KMP_TIME_DEVELOPER_PARTITIONED_BLOCK(USER_resume);
1657 int status;
Jim Cownie07ea89f2014-09-03 11:10:54 +00001658#ifdef KMP_DEBUG
Jonathan Peyton30419822017-05-12 18:01:32 +00001659 int gtid = TCR_4(__kmp_init_gtid) ? __kmp_get_gtid() : -1;
1660 KF_TRACE(30, ("__kmp_resume_monitor: T#%d wants to wakeup T#%d enter\n", gtid,
1661 KMP_GTID_MONITOR));
1662 KMP_DEBUG_ASSERT(gtid != KMP_GTID_MONITOR);
Jim Cownie07ea89f2014-09-03 11:10:54 +00001663#endif
Jonathan Peyton30419822017-05-12 18:01:32 +00001664 status = pthread_mutex_lock(&__kmp_wait_mx.m_mutex);
1665 KMP_CHECK_SYSFAIL("pthread_mutex_lock", status);
Jim Cownie07ea89f2014-09-03 11:10:54 +00001666#ifdef DEBUG_SUSPEND
Jonathan Peyton30419822017-05-12 18:01:32 +00001667 {
1668 char buffer[128];
1669 __kmp_print_cond(buffer, &__kmp_wait_cv.c_cond);
1670 __kmp_printf("__kmp_resume_monitor: T#%d resuming T#%d: %s\n", gtid,
1671 KMP_GTID_MONITOR, buffer);
1672 }
Jim Cownie07ea89f2014-09-03 11:10:54 +00001673#endif
Jonathan Peyton30419822017-05-12 18:01:32 +00001674 status = pthread_cond_signal(&__kmp_wait_cv.c_cond);
1675 KMP_CHECK_SYSFAIL("pthread_cond_signal", status);
1676 status = pthread_mutex_unlock(&__kmp_wait_mx.m_mutex);
1677 KMP_CHECK_SYSFAIL("pthread_mutex_unlock", status);
1678 KF_TRACE(30, ("__kmp_resume_monitor: T#%d exiting after signaling wake up"
1679 " for T#%d\n",
1680 gtid, KMP_GTID_MONITOR));
Jim Cownie07ea89f2014-09-03 11:10:54 +00001681}
Jonathan Peytonb66d1aa2016-09-27 17:11:17 +00001682#endif // KMP_USE_MONITOR
Jim Cownie5e8470a2013-09-27 10:38:44 +00001683
Jonathan Peytone47d32f2019-02-28 19:11:29 +00001684void __kmp_yield() { sched_yield(); }
Jim Cownie5e8470a2013-09-27 10:38:44 +00001685
Jonathan Peyton30419822017-05-12 18:01:32 +00001686void __kmp_gtid_set_specific(int gtid) {
1687 if (__kmp_init_gtid) {
Jim Cownie5e8470a2013-09-27 10:38:44 +00001688 int status;
Jonathan Peyton30419822017-05-12 18:01:32 +00001689 status = pthread_setspecific(__kmp_gtid_threadprivate_key,
1690 (void *)(intptr_t)(gtid + 1));
1691 KMP_CHECK_SYSFAIL("pthread_setspecific", status);
1692 } else {
1693 KA_TRACE(50, ("__kmp_gtid_set_specific: runtime shutdown, returning\n"));
1694 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00001695}
1696
Jonathan Peyton30419822017-05-12 18:01:32 +00001697int __kmp_gtid_get_specific() {
1698 int gtid;
1699 if (!__kmp_init_gtid) {
1700 KA_TRACE(50, ("__kmp_gtid_get_specific: runtime shutdown, returning "
1701 "KMP_GTID_SHUTDOWN\n"));
1702 return KMP_GTID_SHUTDOWN;
1703 }
1704 gtid = (int)(size_t)pthread_getspecific(__kmp_gtid_threadprivate_key);
1705 if (gtid == 0) {
1706 gtid = KMP_GTID_DNE;
1707 } else {
1708 gtid--;
1709 }
1710 KA_TRACE(50, ("__kmp_gtid_get_specific: key:%d gtid:%d\n",
1711 __kmp_gtid_threadprivate_key, gtid));
1712 return gtid;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001713}
1714
Jonathan Peyton30419822017-05-12 18:01:32 +00001715double __kmp_read_cpu_time(void) {
1716 /*clock_t t;*/
1717 struct tms buffer;
1718
1719 /*t =*/times(&buffer);
1720
1721 return (buffer.tms_utime + buffer.tms_cutime) / (double)CLOCKS_PER_SEC;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001722}
1723
Jonathan Peyton30419822017-05-12 18:01:32 +00001724int __kmp_read_system_info(struct kmp_sys_info *info) {
1725 int status;
1726 struct rusage r_usage;
1727
1728 memset(info, 0, sizeof(*info));
1729
1730 status = getrusage(RUSAGE_SELF, &r_usage);
1731 KMP_CHECK_SYSFAIL_ERRNO("getrusage", status);
1732
1733 // The maximum resident set size utilized (in kilobytes)
1734 info->maxrss = r_usage.ru_maxrss;
1735 // The number of page faults serviced without any I/O
1736 info->minflt = r_usage.ru_minflt;
1737 // The number of page faults serviced that required I/O
1738 info->majflt = r_usage.ru_majflt;
1739 // The number of times a process was "swapped" out of memory
1740 info->nswap = r_usage.ru_nswap;
1741 // The number of times the file system had to perform input
1742 info->inblock = r_usage.ru_inblock;
1743 // The number of times the file system had to perform output
1744 info->oublock = r_usage.ru_oublock;
1745 // The number of times a context switch was voluntarily
1746 info->nvcsw = r_usage.ru_nvcsw;
1747 // The number of times a context switch was forced
1748 info->nivcsw = r_usage.ru_nivcsw;
1749
1750 return (status != 0);
1751}
1752
1753void __kmp_read_system_time(double *delta) {
1754 double t_ns;
1755 struct timeval tval;
1756 struct timespec stop;
1757 int status;
1758
1759 status = gettimeofday(&tval, NULL);
1760 KMP_CHECK_SYSFAIL_ERRNO("gettimeofday", status);
1761 TIMEVAL_TO_TIMESPEC(&tval, &stop);
1762 t_ns = TS2NS(stop) - TS2NS(__kmp_sys_timer_data.start);
1763 *delta = (t_ns * 1e-9);
1764}
1765
1766void __kmp_clear_system_time(void) {
1767 struct timeval tval;
1768 int status;
1769 status = gettimeofday(&tval, NULL);
1770 KMP_CHECK_SYSFAIL_ERRNO("gettimeofday", status);
1771 TIMEVAL_TO_TIMESPEC(&tval, &__kmp_sys_timer_data.start);
1772}
Jim Cownie5e8470a2013-09-27 10:38:44 +00001773
Jonathan Peyton30419822017-05-12 18:01:32 +00001774static int __kmp_get_xproc(void) {
Jim Cownie5e8470a2013-09-27 10:38:44 +00001775
Jonathan Peyton30419822017-05-12 18:01:32 +00001776 int r = 0;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001777
Kamil Rytarowskia56ac942018-12-09 16:40:33 +00001778#if KMP_OS_LINUX || KMP_OS_DRAGONFLY || KMP_OS_FREEBSD || KMP_OS_NETBSD || \
Kamil Rytarowski7e1ea992018-12-09 16:46:48 +00001779 KMP_OS_OPENBSD || KMP_OS_HURD
Jim Cownie5e8470a2013-09-27 10:38:44 +00001780
Jonathan Peyton30419822017-05-12 18:01:32 +00001781 r = sysconf(_SC_NPROCESSORS_ONLN);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001782
Jonathan Peyton30419822017-05-12 18:01:32 +00001783#elif KMP_OS_DARWIN
Jim Cownie5e8470a2013-09-27 10:38:44 +00001784
Jonathan Peyton30419822017-05-12 18:01:32 +00001785 // Bug C77011 High "OpenMP Threads and number of active cores".
Jim Cownie5e8470a2013-09-27 10:38:44 +00001786
Jonathan Peyton30419822017-05-12 18:01:32 +00001787 // Find the number of available CPUs.
1788 kern_return_t rc;
1789 host_basic_info_data_t info;
1790 mach_msg_type_number_t num = HOST_BASIC_INFO_COUNT;
1791 rc = host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&info, &num);
1792 if (rc == 0 && num == HOST_BASIC_INFO_COUNT) {
Andrey Churbanovc47afcd2017-07-03 11:24:08 +00001793 // Cannot use KA_TRACE() here because this code works before trace support
1794 // is initialized.
Jonathan Peyton30419822017-05-12 18:01:32 +00001795 r = info.avail_cpus;
1796 } else {
1797 KMP_WARNING(CantGetNumAvailCPU);
1798 KMP_INFORM(AssumedNumCPU);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00001799 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00001800
Jonathan Peyton30419822017-05-12 18:01:32 +00001801#else
Jim Cownie5e8470a2013-09-27 10:38:44 +00001802
Jonathan Peyton30419822017-05-12 18:01:32 +00001803#error "Unknown or unsupported OS."
Jim Cownie5e8470a2013-09-27 10:38:44 +00001804
Jonathan Peyton30419822017-05-12 18:01:32 +00001805#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +00001806
Jonathan Peyton30419822017-05-12 18:01:32 +00001807 return r > 0 ? r : 2; /* guess value of 2 if OS told us 0 */
Jim Cownie5e8470a2013-09-27 10:38:44 +00001808
1809} // __kmp_get_xproc
1810
Jonathan Peyton30419822017-05-12 18:01:32 +00001811int __kmp_read_from_file(char const *path, char const *format, ...) {
1812 int result;
1813 va_list args;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001814
Jonathan Peyton30419822017-05-12 18:01:32 +00001815 va_start(args, format);
1816 FILE *f = fopen(path, "rb");
1817 if (f == NULL)
1818 return 0;
1819 result = vfscanf(f, format, args);
1820 fclose(f);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001821
Jonathan Peyton30419822017-05-12 18:01:32 +00001822 return result;
Jim Cownie181b4bb2013-12-23 17:28:57 +00001823}
Jim Cownie5e8470a2013-09-27 10:38:44 +00001824
Jonathan Peyton30419822017-05-12 18:01:32 +00001825void __kmp_runtime_initialize(void) {
1826 int status;
1827 pthread_mutexattr_t mutex_attr;
1828 pthread_condattr_t cond_attr;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001829
Jonathan Peyton30419822017-05-12 18:01:32 +00001830 if (__kmp_init_runtime) {
1831 return;
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00001832 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00001833
Jonathan Peyton30419822017-05-12 18:01:32 +00001834#if (KMP_ARCH_X86 || KMP_ARCH_X86_64)
1835 if (!__kmp_cpuinfo.initialized) {
1836 __kmp_query_cpuid(&__kmp_cpuinfo);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00001837 }
Jonathan Peyton30419822017-05-12 18:01:32 +00001838#endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
Jim Cownie5e8470a2013-09-27 10:38:44 +00001839
Jonathan Peyton30419822017-05-12 18:01:32 +00001840 __kmp_xproc = __kmp_get_xproc();
Jim Cownie5e8470a2013-09-27 10:38:44 +00001841
Andrey Churbanovd47f5482019-06-05 16:14:47 +00001842#if ! KMP_32_BIT_ARCH
1843 struct rlimit rlim;
1844 // read stack size of calling thread, save it as default for worker threads;
1845 // this should be done before reading environment variables
1846 status = getrlimit(RLIMIT_STACK, &rlim);
1847 if (status == 0) { // success?
1848 __kmp_stksize = rlim.rlim_cur;
1849 __kmp_check_stksize(&__kmp_stksize); // check value and adjust if needed
1850 }
1851#endif /* KMP_32_BIT_ARCH */
1852
Jonathan Peyton30419822017-05-12 18:01:32 +00001853 if (sysconf(_SC_THREADS)) {
Jim Cownie5e8470a2013-09-27 10:38:44 +00001854
Jonathan Peyton30419822017-05-12 18:01:32 +00001855 /* Query the maximum number of threads */
1856 __kmp_sys_max_nth = sysconf(_SC_THREAD_THREADS_MAX);
1857 if (__kmp_sys_max_nth == -1) {
1858 /* Unlimited threads for NPTL */
1859 __kmp_sys_max_nth = INT_MAX;
1860 } else if (__kmp_sys_max_nth <= 1) {
1861 /* Can't tell, just use PTHREAD_THREADS_MAX */
1862 __kmp_sys_max_nth = KMP_MAX_NTH;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001863 }
1864
Jonathan Peyton30419822017-05-12 18:01:32 +00001865 /* Query the minimum stack size */
1866 __kmp_sys_min_stksize = sysconf(_SC_THREAD_STACK_MIN);
1867 if (__kmp_sys_min_stksize <= 1) {
1868 __kmp_sys_min_stksize = KMP_MIN_STKSIZE;
1869 }
1870 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00001871
Jonathan Peyton30419822017-05-12 18:01:32 +00001872 /* Set up minimum number of threads to switch to TLS gtid */
1873 __kmp_tls_gtid_min = KMP_TLS_GTID_MIN;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001874
Jonathan Peyton30419822017-05-12 18:01:32 +00001875 status = pthread_key_create(&__kmp_gtid_threadprivate_key,
1876 __kmp_internal_end_dest);
1877 KMP_CHECK_SYSFAIL("pthread_key_create", status);
1878 status = pthread_mutexattr_init(&mutex_attr);
1879 KMP_CHECK_SYSFAIL("pthread_mutexattr_init", status);
1880 status = pthread_mutex_init(&__kmp_wait_mx.m_mutex, &mutex_attr);
1881 KMP_CHECK_SYSFAIL("pthread_mutex_init", status);
1882 status = pthread_condattr_init(&cond_attr);
1883 KMP_CHECK_SYSFAIL("pthread_condattr_init", status);
1884 status = pthread_cond_init(&__kmp_wait_cv.c_cond, &cond_attr);
1885 KMP_CHECK_SYSFAIL("pthread_cond_init", status);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001886#if USE_ITT_BUILD
Jonathan Peyton30419822017-05-12 18:01:32 +00001887 __kmp_itt_initialize();
Jim Cownie5e8470a2013-09-27 10:38:44 +00001888#endif /* USE_ITT_BUILD */
1889
Jonathan Peyton30419822017-05-12 18:01:32 +00001890 __kmp_init_runtime = TRUE;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001891}
1892
Jonathan Peyton30419822017-05-12 18:01:32 +00001893void __kmp_runtime_destroy(void) {
1894 int status;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001895
Jonathan Peyton30419822017-05-12 18:01:32 +00001896 if (!__kmp_init_runtime) {
1897 return; // Nothing to do.
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00001898 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00001899
1900#if USE_ITT_BUILD
Jonathan Peyton30419822017-05-12 18:01:32 +00001901 __kmp_itt_destroy();
Jim Cownie5e8470a2013-09-27 10:38:44 +00001902#endif /* USE_ITT_BUILD */
1903
Jonathan Peyton30419822017-05-12 18:01:32 +00001904 status = pthread_key_delete(__kmp_gtid_threadprivate_key);
1905 KMP_CHECK_SYSFAIL("pthread_key_delete", status);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001906
Jonathan Peyton30419822017-05-12 18:01:32 +00001907 status = pthread_mutex_destroy(&__kmp_wait_mx.m_mutex);
1908 if (status != 0 && status != EBUSY) {
1909 KMP_SYSFAIL("pthread_mutex_destroy", status);
1910 }
1911 status = pthread_cond_destroy(&__kmp_wait_cv.c_cond);
1912 if (status != 0 && status != EBUSY) {
1913 KMP_SYSFAIL("pthread_cond_destroy", status);
1914 }
1915#if KMP_AFFINITY_SUPPORTED
1916 __kmp_affinity_uninitialize();
1917#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +00001918
Jonathan Peyton30419822017-05-12 18:01:32 +00001919 __kmp_init_runtime = FALSE;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001920}
1921
Jim Cownie5e8470a2013-09-27 10:38:44 +00001922/* Put the thread to sleep for a time period */
1923/* NOTE: not currently used anywhere */
Jonathan Peyton30419822017-05-12 18:01:32 +00001924void __kmp_thread_sleep(int millis) { sleep((millis + 500) / 1000); }
Jim Cownie5e8470a2013-09-27 10:38:44 +00001925
1926/* Calculate the elapsed wall clock time for the user */
Jonathan Peyton30419822017-05-12 18:01:32 +00001927void __kmp_elapsed(double *t) {
1928 int status;
1929#ifdef FIX_SGI_CLOCK
1930 struct timespec ts;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001931
Jonathan Peyton30419822017-05-12 18:01:32 +00001932 status = clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
1933 KMP_CHECK_SYSFAIL_ERRNO("clock_gettime", status);
1934 *t =
1935 (double)ts.tv_nsec * (1.0 / (double)KMP_NSEC_PER_SEC) + (double)ts.tv_sec;
1936#else
1937 struct timeval tv;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001938
Jonathan Peyton30419822017-05-12 18:01:32 +00001939 status = gettimeofday(&tv, NULL);
1940 KMP_CHECK_SYSFAIL_ERRNO("gettimeofday", status);
1941 *t =
1942 (double)tv.tv_usec * (1.0 / (double)KMP_USEC_PER_SEC) + (double)tv.tv_sec;
1943#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +00001944}
1945
1946/* Calculate the elapsed wall clock tick for the user */
Jonathan Peyton30419822017-05-12 18:01:32 +00001947void __kmp_elapsed_tick(double *t) { *t = 1 / (double)CLOCKS_PER_SEC; }
Jim Cownie5e8470a2013-09-27 10:38:44 +00001948
Jonathan Peyton377aa402016-04-14 16:00:37 +00001949/* Return the current time stamp in nsec */
Jonathan Peyton30419822017-05-12 18:01:32 +00001950kmp_uint64 __kmp_now_nsec() {
1951 struct timeval t;
1952 gettimeofday(&t, NULL);
Jonathan Peytonbdb0a2f2018-12-13 23:18:55 +00001953 kmp_uint64 nsec = (kmp_uint64)KMP_NSEC_PER_SEC * (kmp_uint64)t.tv_sec +
1954 (kmp_uint64)1000 * (kmp_uint64)t.tv_usec;
1955 return nsec;
Jonathan Peyton377aa402016-04-14 16:00:37 +00001956}
1957
Jonathan Peytonb66d1aa2016-09-27 17:11:17 +00001958#if KMP_ARCH_X86 || KMP_ARCH_X86_64
Jonathan Peyton35d75ae2017-03-20 22:11:31 +00001959/* Measure clock ticks per millisecond */
Jonathan Peyton30419822017-05-12 18:01:32 +00001960void __kmp_initialize_system_tick() {
Jonathan Peytonbdb0a2f2018-12-13 23:18:55 +00001961 kmp_uint64 now, nsec2, diff;
Jonathan Peyton30419822017-05-12 18:01:32 +00001962 kmp_uint64 delay = 100000; // 50~100 usec on most machines.
1963 kmp_uint64 nsec = __kmp_now_nsec();
1964 kmp_uint64 goal = __kmp_hardware_timestamp() + delay;
Jonathan Peyton30419822017-05-12 18:01:32 +00001965 while ((now = __kmp_hardware_timestamp()) < goal)
1966 ;
Jonathan Peytonbdb0a2f2018-12-13 23:18:55 +00001967 nsec2 = __kmp_now_nsec();
1968 diff = nsec2 - nsec;
1969 if (diff > 0) {
1970 kmp_uint64 tpms = (kmp_uint64)(1e6 * (delay + (now - goal)) / diff);
1971 if (tpms > 0)
1972 __kmp_ticks_per_msec = tpms;
1973 }
Jonathan Peytonb66d1aa2016-09-27 17:11:17 +00001974}
1975#endif
1976
Jonathan Peyton30419822017-05-12 18:01:32 +00001977/* Determine whether the given address is mapped into the current address
1978 space. */
Jim Cownie5e8470a2013-09-27 10:38:44 +00001979
Jonathan Peyton30419822017-05-12 18:01:32 +00001980int __kmp_is_address_mapped(void *addr) {
Jim Cownie5e8470a2013-09-27 10:38:44 +00001981
Jonathan Peyton30419822017-05-12 18:01:32 +00001982 int found = 0;
1983 int rc;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001984
David Carlierfef62e12019-09-28 19:01:59 +00001985#if KMP_OS_LINUX || KMP_OS_HURD
Jim Cownie5e8470a2013-09-27 10:38:44 +00001986
Andrey Churbanov855d0982018-11-07 12:27:38 +00001987 /* On GNUish OSes, read the /proc/<pid>/maps pseudo-file to get all the address
Jonathan Peyton30419822017-05-12 18:01:32 +00001988 ranges mapped into the address space. */
Jim Cownie5e8470a2013-09-27 10:38:44 +00001989
Jonathan Peyton30419822017-05-12 18:01:32 +00001990 char *name = __kmp_str_format("/proc/%d/maps", getpid());
1991 FILE *file = NULL;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001992
Jonathan Peyton30419822017-05-12 18:01:32 +00001993 file = fopen(name, "r");
1994 KMP_ASSERT(file != NULL);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001995
Jonathan Peyton30419822017-05-12 18:01:32 +00001996 for (;;) {
Jim Cownie5e8470a2013-09-27 10:38:44 +00001997
Jonathan Peyton30419822017-05-12 18:01:32 +00001998 void *beginning = NULL;
1999 void *ending = NULL;
2000 char perms[5];
Jim Cownie5e8470a2013-09-27 10:38:44 +00002001
Jonathan Peyton30419822017-05-12 18:01:32 +00002002 rc = fscanf(file, "%p-%p %4s %*[^\n]\n", &beginning, &ending, perms);
2003 if (rc == EOF) {
2004 break;
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00002005 }
Jonathan Peyton30419822017-05-12 18:01:32 +00002006 KMP_ASSERT(rc == 3 &&
2007 KMP_STRLEN(perms) == 4); // Make sure all fields are read.
Jim Cownie5e8470a2013-09-27 10:38:44 +00002008
Jonathan Peyton30419822017-05-12 18:01:32 +00002009 // Ending address is not included in the region, but beginning is.
2010 if ((addr >= beginning) && (addr < ending)) {
2011 perms[2] = 0; // 3th and 4th character does not matter.
2012 if (strcmp(perms, "rw") == 0) {
2013 // Memory we are looking for should be readable and writable.
Alp Toker763b9392014-02-28 09:42:41 +00002014 found = 1;
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00002015 }
Jonathan Peyton30419822017-05-12 18:01:32 +00002016 break;
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00002017 }
2018 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00002019
Jonathan Peyton30419822017-05-12 18:01:32 +00002020 // Free resources.
2021 fclose(file);
2022 KMP_INTERNAL_FREE(name);
David Carlierfef62e12019-09-28 19:01:59 +00002023#elif KMP_OS_FREEBSD
2024 char *buf;
2025 size_t lstsz;
2026 int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_VMMAP, getpid()};
2027 rc = sysctl(mib, 4, NULL, &lstsz, NULL, 0);
2028 if (rc < 0)
2029 return 0;
2030 // We pass from number of vm entry's semantic
2031 // to size of whole entry map list.
2032 lstsz = lstsz * 4 / 3;
2033 buf = reinterpret_cast<char *>(kmpc_malloc(lstsz));
2034 rc = sysctl(mib, 4, buf, &lstsz, NULL, 0);
2035 if (rc < 0) {
2036 kmpc_free(buf);
2037 return 0;
2038 }
2039
2040 char *lw = buf;
2041 char *up = buf + lstsz;
2042
2043 while (lw < up) {
2044 struct kinfo_vmentry *cur = reinterpret_cast<struct kinfo_vmentry *>(lw);
2045 size_t cursz = cur->kve_structsize;
2046 if (cursz == 0)
2047 break;
2048 void *start = reinterpret_cast<void *>(cur->kve_start);
2049 void *end = reinterpret_cast<void *>(cur->kve_end);
2050 // Readable/Writable addresses within current map entry
2051 if ((addr >= start) && (addr < end)) {
2052 if ((cur->kve_protection & KVME_PROT_READ) != 0 &&
2053 (cur->kve_protection & KVME_PROT_WRITE) != 0) {
2054 found = 1;
2055 break;
2056 }
2057 }
2058 lw += cursz;
2059 }
2060 kmpc_free(buf);
Jim Cownie5e8470a2013-09-27 10:38:44 +00002061
Jonathan Peyton30419822017-05-12 18:01:32 +00002062#elif KMP_OS_DARWIN
Jim Cownie5e8470a2013-09-27 10:38:44 +00002063
Jonathan Peyton30419822017-05-12 18:01:32 +00002064 /* On OS X*, /proc pseudo filesystem is not available. Try to read memory
2065 using vm interface. */
2066
2067 int buffer;
2068 vm_size_t count;
2069 rc = vm_read_overwrite(
2070 mach_task_self(), // Task to read memory of.
2071 (vm_address_t)(addr), // Address to read from.
2072 1, // Number of bytes to be read.
2073 (vm_address_t)(&buffer), // Address of buffer to save read bytes in.
2074 &count // Address of var to save number of read bytes in.
2075 );
2076 if (rc == 0) {
2077 // Memory successfully read.
2078 found = 1;
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00002079 }
Jonathan Peyton30419822017-05-12 18:01:32 +00002080
Kamil Rytarowski316f4232018-12-11 18:35:07 +00002081#elif KMP_OS_NETBSD
Jonathan Peyton30419822017-05-12 18:01:32 +00002082
Kamil Rytarowski316f4232018-12-11 18:35:07 +00002083 int mib[5];
2084 mib[0] = CTL_VM;
2085 mib[1] = VM_PROC;
2086 mib[2] = VM_PROC_MAP;
2087 mib[3] = getpid();
2088 mib[4] = sizeof(struct kinfo_vmentry);
2089
2090 size_t size;
2091 rc = sysctl(mib, __arraycount(mib), NULL, &size, NULL, 0);
2092 KMP_ASSERT(!rc);
2093 KMP_ASSERT(size);
2094
2095 size = size * 4 / 3;
2096 struct kinfo_vmentry *kiv = (struct kinfo_vmentry *)KMP_INTERNAL_MALLOC(size);
2097 KMP_ASSERT(kiv);
2098
2099 rc = sysctl(mib, __arraycount(mib), kiv, &size, NULL, 0);
2100 KMP_ASSERT(!rc);
2101 KMP_ASSERT(size);
2102
2103 for (size_t i = 0; i < size; i++) {
2104 if (kiv[i].kve_start >= (uint64_t)addr &&
2105 kiv[i].kve_end <= (uint64_t)addr) {
2106 found = 1;
2107 break;
2108 }
2109 }
2110 KMP_INTERNAL_FREE(kiv);
2111#elif KMP_OS_DRAGONFLY || KMP_OS_OPENBSD
2112
2113 // FIXME(DragonFly, OpenBSD): Implement this
Jonathan Peyton30419822017-05-12 18:01:32 +00002114 found = 1;
2115
2116#else
2117
2118#error "Unknown or unsupported OS"
2119
2120#endif
2121
2122 return found;
Jim Cownie5e8470a2013-09-27 10:38:44 +00002123
2124} // __kmp_is_address_mapped
2125
2126#ifdef USE_LOAD_BALANCE
2127
Michal Gorny70cdd832018-12-11 19:02:09 +00002128#if KMP_OS_DARWIN || KMP_OS_NETBSD
Jim Cownie5e8470a2013-09-27 10:38:44 +00002129
2130// The function returns the rounded value of the system load average
2131// during given time interval which depends on the value of
2132// __kmp_load_balance_interval variable (default is 60 sec, other values
2133// may be 300 sec or 900 sec).
2134// It returns -1 in case of error.
Jonathan Peyton30419822017-05-12 18:01:32 +00002135int __kmp_get_load_balance(int max) {
2136 double averages[3];
2137 int ret_avg = 0;
Jim Cownie5e8470a2013-09-27 10:38:44 +00002138
Jonathan Peyton30419822017-05-12 18:01:32 +00002139 int res = getloadavg(averages, 3);
Jim Cownie5e8470a2013-09-27 10:38:44 +00002140
Jonathan Peyton30419822017-05-12 18:01:32 +00002141 // Check __kmp_load_balance_interval to determine which of averages to use.
2142 // getloadavg() may return the number of samples less than requested that is
2143 // less than 3.
2144 if (__kmp_load_balance_interval < 180 && (res >= 1)) {
2145 ret_avg = averages[0]; // 1 min
2146 } else if ((__kmp_load_balance_interval >= 180 &&
2147 __kmp_load_balance_interval < 600) &&
2148 (res >= 2)) {
2149 ret_avg = averages[1]; // 5 min
2150 } else if ((__kmp_load_balance_interval >= 600) && (res == 3)) {
2151 ret_avg = averages[2]; // 15 min
2152 } else { // Error occurred
2153 return -1;
2154 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00002155
Jonathan Peyton30419822017-05-12 18:01:32 +00002156 return ret_avg;
Jim Cownie5e8470a2013-09-27 10:38:44 +00002157}
2158
Jonathan Peyton30419822017-05-12 18:01:32 +00002159#else // Linux* OS
Jim Cownie5e8470a2013-09-27 10:38:44 +00002160
Jonathan Peyton30419822017-05-12 18:01:32 +00002161// The fuction returns number of running (not sleeping) threads, or -1 in case
2162// of error. Error could be reported if Linux* OS kernel too old (without
2163// "/proc" support). Counting running threads stops if max running threads
2164// encountered.
2165int __kmp_get_load_balance(int max) {
2166 static int permanent_error = 0;
2167 static int glb_running_threads = 0; // Saved count of the running threads for
2168 // the thread balance algortihm
2169 static double glb_call_time = 0; /* Thread balance algorithm call time */
Jim Cownie5e8470a2013-09-27 10:38:44 +00002170
Jonathan Peyton30419822017-05-12 18:01:32 +00002171 int running_threads = 0; // Number of running threads in the system.
Jim Cownie5e8470a2013-09-27 10:38:44 +00002172
Jonathan Peyton30419822017-05-12 18:01:32 +00002173 DIR *proc_dir = NULL; // Handle of "/proc/" directory.
2174 struct dirent *proc_entry = NULL;
Jim Cownie5e8470a2013-09-27 10:38:44 +00002175
Jonathan Peyton30419822017-05-12 18:01:32 +00002176 kmp_str_buf_t task_path; // "/proc/<pid>/task/<tid>/" path.
2177 DIR *task_dir = NULL; // Handle of "/proc/<pid>/task/<tid>/" directory.
2178 struct dirent *task_entry = NULL;
2179 int task_path_fixed_len;
Jim Cownie5e8470a2013-09-27 10:38:44 +00002180
Jonathan Peyton30419822017-05-12 18:01:32 +00002181 kmp_str_buf_t stat_path; // "/proc/<pid>/task/<tid>/stat" path.
2182 int stat_file = -1;
2183 int stat_path_fixed_len;
Jim Cownie5e8470a2013-09-27 10:38:44 +00002184
Jonathan Peyton30419822017-05-12 18:01:32 +00002185 int total_processes = 0; // Total number of processes in system.
2186 int total_threads = 0; // Total number of threads in system.
Jim Cownie5e8470a2013-09-27 10:38:44 +00002187
Jonathan Peyton30419822017-05-12 18:01:32 +00002188 double call_time = 0.0;
Jim Cownie5e8470a2013-09-27 10:38:44 +00002189
Jonathan Peyton30419822017-05-12 18:01:32 +00002190 __kmp_str_buf_init(&task_path);
2191 __kmp_str_buf_init(&stat_path);
Jim Cownie5e8470a2013-09-27 10:38:44 +00002192
Jonathan Peyton30419822017-05-12 18:01:32 +00002193 __kmp_elapsed(&call_time);
Jim Cownie5e8470a2013-09-27 10:38:44 +00002194
Jonathan Peyton30419822017-05-12 18:01:32 +00002195 if (glb_call_time &&
2196 (call_time - glb_call_time < __kmp_load_balance_interval)) {
2197 running_threads = glb_running_threads;
2198 goto finish;
2199 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00002200
Jonathan Peyton30419822017-05-12 18:01:32 +00002201 glb_call_time = call_time;
Jim Cownie5e8470a2013-09-27 10:38:44 +00002202
Jonathan Peyton30419822017-05-12 18:01:32 +00002203 // Do not spend time on scanning "/proc/" if we have a permanent error.
2204 if (permanent_error) {
2205 running_threads = -1;
2206 goto finish;
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00002207 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00002208
Jonathan Peyton30419822017-05-12 18:01:32 +00002209 if (max <= 0) {
2210 max = INT_MAX;
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00002211 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00002212
Jonathan Peyton30419822017-05-12 18:01:32 +00002213 // Open "/proc/" directory.
2214 proc_dir = opendir("/proc");
2215 if (proc_dir == NULL) {
2216 // Cannot open "/prroc/". Probably the kernel does not support it. Return an
2217 // error now and in subsequent calls.
2218 running_threads = -1;
2219 permanent_error = 1;
2220 goto finish;
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00002221 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00002222
Jonathan Peyton30419822017-05-12 18:01:32 +00002223 // Initialize fixed part of task_path. This part will not change.
2224 __kmp_str_buf_cat(&task_path, "/proc/", 6);
2225 task_path_fixed_len = task_path.used; // Remember number of used characters.
Jim Cownie5e8470a2013-09-27 10:38:44 +00002226
Jonathan Peyton30419822017-05-12 18:01:32 +00002227 proc_entry = readdir(proc_dir);
2228 while (proc_entry != NULL) {
2229 // Proc entry is a directory and name starts with a digit. Assume it is a
2230 // process' directory.
2231 if (proc_entry->d_type == DT_DIR && isdigit(proc_entry->d_name[0])) {
Jim Cownie5e8470a2013-09-27 10:38:44 +00002232
Jonathan Peyton30419822017-05-12 18:01:32 +00002233 ++total_processes;
2234 // Make sure init process is the very first in "/proc", so we can replace
2235 // strcmp( proc_entry->d_name, "1" ) == 0 with simpler total_processes ==
2236 // 1. We are going to check that total_processes == 1 => d_name == "1" is
2237 // true (where "=>" is implication). Since C++ does not have => operator,
2238 // let us replace it with its equivalent: a => b == ! a || b.
2239 KMP_DEBUG_ASSERT(total_processes != 1 ||
2240 strcmp(proc_entry->d_name, "1") == 0);
Jim Cownie5e8470a2013-09-27 10:38:44 +00002241
Jonathan Peyton30419822017-05-12 18:01:32 +00002242 // Construct task_path.
2243 task_path.used = task_path_fixed_len; // Reset task_path to "/proc/".
2244 __kmp_str_buf_cat(&task_path, proc_entry->d_name,
2245 KMP_STRLEN(proc_entry->d_name));
2246 __kmp_str_buf_cat(&task_path, "/task", 5);
Jim Cownie5e8470a2013-09-27 10:38:44 +00002247
Jonathan Peyton30419822017-05-12 18:01:32 +00002248 task_dir = opendir(task_path.str);
2249 if (task_dir == NULL) {
2250 // Process can finish between reading "/proc/" directory entry and
2251 // opening process' "task/" directory. So, in general case we should not
2252 // complain, but have to skip this process and read the next one. But on
2253 // systems with no "task/" support we will spend lot of time to scan
2254 // "/proc/" tree again and again without any benefit. "init" process
2255 // (its pid is 1) should exist always, so, if we cannot open
2256 // "/proc/1/task/" directory, it means "task/" is not supported by
2257 // kernel. Report an error now and in the future.
2258 if (strcmp(proc_entry->d_name, "1") == 0) {
2259 running_threads = -1;
2260 permanent_error = 1;
2261 goto finish;
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00002262 }
Jonathan Peyton30419822017-05-12 18:01:32 +00002263 } else {
2264 // Construct fixed part of stat file path.
2265 __kmp_str_buf_clear(&stat_path);
2266 __kmp_str_buf_cat(&stat_path, task_path.str, task_path.used);
2267 __kmp_str_buf_cat(&stat_path, "/", 1);
2268 stat_path_fixed_len = stat_path.used;
Jim Cownie5e8470a2013-09-27 10:38:44 +00002269
Jonathan Peyton30419822017-05-12 18:01:32 +00002270 task_entry = readdir(task_dir);
2271 while (task_entry != NULL) {
2272 // It is a directory and name starts with a digit.
2273 if (proc_entry->d_type == DT_DIR && isdigit(task_entry->d_name[0])) {
2274 ++total_threads;
2275
2276 // Consruct complete stat file path. Easiest way would be:
2277 // __kmp_str_buf_print( & stat_path, "%s/%s/stat", task_path.str,
2278 // task_entry->d_name );
2279 // but seriae of __kmp_str_buf_cat works a bit faster.
2280 stat_path.used =
2281 stat_path_fixed_len; // Reset stat path to its fixed part.
2282 __kmp_str_buf_cat(&stat_path, task_entry->d_name,
2283 KMP_STRLEN(task_entry->d_name));
2284 __kmp_str_buf_cat(&stat_path, "/stat", 5);
2285
2286 // Note: Low-level API (open/read/close) is used. High-level API
2287 // (fopen/fclose) works ~ 30 % slower.
2288 stat_file = open(stat_path.str, O_RDONLY);
2289 if (stat_file == -1) {
2290 // We cannot report an error because task (thread) can terminate
2291 // just before reading this file.
Jim Cownie5e8470a2013-09-27 10:38:44 +00002292 } else {
Jonathan Peyton30419822017-05-12 18:01:32 +00002293 /* Content of "stat" file looks like:
2294 24285 (program) S ...
Jim Cownie5e8470a2013-09-27 10:38:44 +00002295
Jonathan Peyton30419822017-05-12 18:01:32 +00002296 It is a single line (if program name does not include funny
2297 symbols). First number is a thread id, then name of executable
2298 file name in paretheses, then state of the thread. We need just
2299 thread state.
Jim Cownie5e8470a2013-09-27 10:38:44 +00002300
Jonathan Peyton30419822017-05-12 18:01:32 +00002301 Good news: Length of program name is 15 characters max. Longer
2302 names are truncated.
Jim Cownie5e8470a2013-09-27 10:38:44 +00002303
Jonathan Peyton30419822017-05-12 18:01:32 +00002304 Thus, we need rather short buffer: 15 chars for program name +
2305 2 parenthesis, + 3 spaces + ~7 digits of pid = 37.
Jim Cownie5e8470a2013-09-27 10:38:44 +00002306
Jonathan Peyton30419822017-05-12 18:01:32 +00002307 Bad news: Program name may contain special symbols like space,
2308 closing parenthesis, or even new line. This makes parsing
2309 "stat" file not 100 % reliable. In case of fanny program names
2310 parsing may fail (report incorrect thread state).
Jim Cownie5e8470a2013-09-27 10:38:44 +00002311
Jonathan Peyton30419822017-05-12 18:01:32 +00002312 Parsing "status" file looks more promissing (due to different
2313 file structure and escaping special symbols) but reading and
2314 parsing of "status" file works slower.
2315 -- ln
2316 */
2317 char buffer[65];
2318 int len;
2319 len = read(stat_file, buffer, sizeof(buffer) - 1);
2320 if (len >= 0) {
2321 buffer[len] = 0;
2322 // Using scanf:
2323 // sscanf( buffer, "%*d (%*s) %c ", & state );
2324 // looks very nice, but searching for a closing parenthesis
2325 // works a bit faster.
2326 char *close_parent = strstr(buffer, ") ");
2327 if (close_parent != NULL) {
2328 char state = *(close_parent + 2);
2329 if (state == 'R') {
2330 ++running_threads;
2331 if (running_threads >= max) {
2332 goto finish;
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00002333 }
2334 }
2335 }
2336 }
Jonathan Peyton30419822017-05-12 18:01:32 +00002337 close(stat_file);
2338 stat_file = -1;
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00002339 }
2340 }
Jonathan Peyton30419822017-05-12 18:01:32 +00002341 task_entry = readdir(task_dir);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00002342 }
Jonathan Peyton30419822017-05-12 18:01:32 +00002343 closedir(task_dir);
2344 task_dir = NULL;
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00002345 }
2346 }
Jonathan Peyton30419822017-05-12 18:01:32 +00002347 proc_entry = readdir(proc_dir);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00002348 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00002349
Jonathan Peyton30419822017-05-12 18:01:32 +00002350 // There _might_ be a timing hole where the thread executing this
2351 // code get skipped in the load balance, and running_threads is 0.
2352 // Assert in the debug builds only!!!
2353 KMP_DEBUG_ASSERT(running_threads > 0);
2354 if (running_threads <= 0) {
2355 running_threads = 1;
2356 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00002357
Jonathan Peyton30419822017-05-12 18:01:32 +00002358finish: // Clean up and exit.
2359 if (proc_dir != NULL) {
2360 closedir(proc_dir);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00002361 }
Jonathan Peyton30419822017-05-12 18:01:32 +00002362 __kmp_str_buf_free(&task_path);
2363 if (task_dir != NULL) {
2364 closedir(task_dir);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00002365 }
Jonathan Peyton30419822017-05-12 18:01:32 +00002366 __kmp_str_buf_free(&stat_path);
2367 if (stat_file != -1) {
2368 close(stat_file);
Jonathan Peytonbd3a7632017-09-27 20:36:27 +00002369 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00002370
Jonathan Peyton30419822017-05-12 18:01:32 +00002371 glb_running_threads = running_threads;
Jim Cownie5e8470a2013-09-27 10:38:44 +00002372
Jonathan Peyton30419822017-05-12 18:01:32 +00002373 return running_threads;
Jim Cownie5e8470a2013-09-27 10:38:44 +00002374
2375} // __kmp_get_load_balance
2376
Jonathan Peyton30419822017-05-12 18:01:32 +00002377#endif // KMP_OS_DARWIN
Jim Cownie5e8470a2013-09-27 10:38:44 +00002378
2379#endif // USE_LOAD_BALANCE
2380
Andrey Churbanovc47afcd2017-07-03 11:24:08 +00002381#if !(KMP_ARCH_X86 || KMP_ARCH_X86_64 || KMP_MIC || \
Jonas Hahnfeld2488ae92019-07-25 14:36:20 +00002382 ((KMP_OS_LINUX || KMP_OS_DARWIN) && KMP_ARCH_AARCH64) || \
2383 KMP_ARCH_PPC64 || KMP_ARCH_RISCV64)
Jim Cownie3051f972014-08-07 10:12:54 +00002384
2385// we really only need the case with 1 argument, because CLANG always build
2386// a struct of pointers to shared variables referenced in the outlined function
Jonathan Peyton30419822017-05-12 18:01:32 +00002387int __kmp_invoke_microtask(microtask_t pkfn, int gtid, int tid, int argc,
2388 void *p_argv[]
Jonathan Peyton122dd762015-07-13 18:55:45 +00002389#if OMPT_SUPPORT
Jonathan Peyton30419822017-05-12 18:01:32 +00002390 ,
2391 void **exit_frame_ptr
Jonathan Peyton122dd762015-07-13 18:55:45 +00002392#endif
Jonathan Peyton30419822017-05-12 18:01:32 +00002393 ) {
Jonathan Peyton122dd762015-07-13 18:55:45 +00002394#if OMPT_SUPPORT
Joachim Protze82e94a52017-11-01 10:08:30 +00002395 *exit_frame_ptr = OMPT_GET_FRAME_ADDRESS(0);
Jonathan Peyton122dd762015-07-13 18:55:45 +00002396#endif
2397
Jim Cownie3051f972014-08-07 10:12:54 +00002398 switch (argc) {
2399 default:
2400 fprintf(stderr, "Too many args to microtask: %d!\n", argc);
2401 fflush(stderr);
2402 exit(-1);
2403 case 0:
2404 (*pkfn)(&gtid, &tid);
2405 break;
2406 case 1:
2407 (*pkfn)(&gtid, &tid, p_argv[0]);
2408 break;
2409 case 2:
2410 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1]);
2411 break;
2412 case 3:
2413 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2]);
2414 break;
2415 case 4:
2416 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3]);
2417 break;
2418 case 5:
2419 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4]);
2420 break;
2421 case 6:
2422 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2423 p_argv[5]);
2424 break;
2425 case 7:
2426 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2427 p_argv[5], p_argv[6]);
2428 break;
2429 case 8:
2430 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2431 p_argv[5], p_argv[6], p_argv[7]);
2432 break;
2433 case 9:
2434 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2435 p_argv[5], p_argv[6], p_argv[7], p_argv[8]);
2436 break;
2437 case 10:
2438 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2439 p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9]);
2440 break;
2441 case 11:
2442 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2443 p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9], p_argv[10]);
2444 break;
2445 case 12:
2446 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2447 p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9], p_argv[10],
2448 p_argv[11]);
2449 break;
2450 case 13:
2451 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2452 p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9], p_argv[10],
2453 p_argv[11], p_argv[12]);
2454 break;
2455 case 14:
2456 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2457 p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9], p_argv[10],
2458 p_argv[11], p_argv[12], p_argv[13]);
2459 break;
2460 case 15:
2461 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2462 p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9], p_argv[10],
2463 p_argv[11], p_argv[12], p_argv[13], p_argv[14]);
2464 break;
2465 }
2466
2467 return 1;
2468}
2469
2470#endif
Jim Cownie181b4bb2013-12-23 17:28:57 +00002471
Jim Cownie5e8470a2013-09-27 10:38:44 +00002472// end of file //