blob: 5d61cd177febfebf966465b0930cbb7f499ec523 [file] [log] [blame]
Jim Cownie5e8470a2013-09-27 10:38:44 +00001/*
2 * z_Linux_util.c -- platform specific routines.
Jim Cownie5e8470a2013-09-27 10:38:44 +00003 */
4
5
6//===----------------------------------------------------------------------===//
7//
8// The LLVM Compiler Infrastructure
9//
10// This file is dual licensed under the MIT and the University of Illinois Open
11// Source Licenses. See LICENSE.txt for details.
12//
13//===----------------------------------------------------------------------===//
14
15
16#include "kmp.h"
17#include "kmp_wrapper_getpid.h"
18#include "kmp_itt.h"
19#include "kmp_str.h"
20#include "kmp_i18n.h"
21#include "kmp_io.h"
Jim Cownie4cc4bb42014-10-07 16:25:50 +000022#include "kmp_stats.h"
23#include "kmp_wait_release.h"
Jim Cownie5e8470a2013-09-27 10:38:44 +000024
Joerg Sonnenberger1564f3c2015-09-21 20:02:45 +000025#if !KMP_OS_FREEBSD && !KMP_OS_NETBSD
Alp Toker763b9392014-02-28 09:42:41 +000026# include <alloca.h>
27#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +000028#include <unistd.h>
29#include <math.h> // HUGE_VAL.
30#include <sys/time.h>
31#include <sys/times.h>
32#include <sys/resource.h>
33#include <sys/syscall.h>
34
Jim Cownie3051f972014-08-07 10:12:54 +000035#if KMP_OS_LINUX && !KMP_OS_CNK
Jim Cownie5e8470a2013-09-27 10:38:44 +000036# include <sys/sysinfo.h>
Andrey Churbanovcbda8682015-01-13 14:43:35 +000037# if KMP_OS_LINUX && (KMP_ARCH_X86 || KMP_ARCH_X86_64 || KMP_ARCH_ARM || KMP_ARCH_AARCH64)
Jim Cownie5e8470a2013-09-27 10:38:44 +000038// We should really include <futex.h>, but that causes compatibility problems on different
39// Linux* OS distributions that either require that you include (or break when you try to include)
40// <pci/types.h>.
41// Since all we need is the two macros below (which are part of the kernel ABI, so can't change)
42// we just define the constants here and don't include <futex.h>
43# ifndef FUTEX_WAIT
44# define FUTEX_WAIT 0
45# endif
46# ifndef FUTEX_WAKE
47# define FUTEX_WAKE 1
48# endif
49# endif
50#elif KMP_OS_DARWIN
51# include <sys/sysctl.h>
52# include <mach/mach.h>
Alp Toker763b9392014-02-28 09:42:41 +000053#elif KMP_OS_FREEBSD
Alp Toker763b9392014-02-28 09:42:41 +000054# include <pthread_np.h>
Jim Cownie5e8470a2013-09-27 10:38:44 +000055#endif
56
Jim Cownie5e8470a2013-09-27 10:38:44 +000057#include <dirent.h>
58#include <ctype.h>
59#include <fcntl.h>
60
61/* ------------------------------------------------------------------------ */
62/* ------------------------------------------------------------------------ */
63
64struct kmp_sys_timer {
65 struct timespec start;
66};
67
68// Convert timespec to nanoseconds.
69#define TS2NS(timespec) (((timespec).tv_sec * 1e9) + (timespec).tv_nsec)
70
71static struct kmp_sys_timer __kmp_sys_timer_data;
72
73#if KMP_HANDLE_SIGNALS
74 typedef void (* sig_func_t )( int );
75 STATIC_EFI2_WORKAROUND struct sigaction __kmp_sighldrs[ NSIG ];
76 static sigset_t __kmp_sigset;
77#endif
78
79static int __kmp_init_runtime = FALSE;
80
81static int __kmp_fork_count = 0;
82
83static pthread_condattr_t __kmp_suspend_cond_attr;
84static pthread_mutexattr_t __kmp_suspend_mutex_attr;
85
86static kmp_cond_align_t __kmp_wait_cv;
87static kmp_mutex_align_t __kmp_wait_mx;
88
89/* ------------------------------------------------------------------------ */
90/* ------------------------------------------------------------------------ */
91
92#ifdef DEBUG_SUSPEND
93static void
94__kmp_print_cond( char *buffer, kmp_cond_align_t *cond )
95{
Andrey Churbanov74bf17b2015-04-02 13:27:08 +000096 KMP_SNPRINTF( buffer, 128, "(cond (lock (%ld, %d)), (descr (%p)))",
Jim Cownie5e8470a2013-09-27 10:38:44 +000097 cond->c_cond.__c_lock.__status, cond->c_cond.__c_lock.__spinlock,
98 cond->c_cond.__c_waiting );
99}
100#endif
101
102/* ------------------------------------------------------------------------ */
103/* ------------------------------------------------------------------------ */
104
Jim Cownie3051f972014-08-07 10:12:54 +0000105#if ( KMP_OS_LINUX && KMP_AFFINITY_SUPPORTED)
Jim Cownie5e8470a2013-09-27 10:38:44 +0000106
107/*
108 * Affinity support
109 */
110
111/*
112 * On some of the older OS's that we build on, these constants aren't present
113 * in <asm/unistd.h> #included from <sys.syscall.h>. They must be the same on
114 * all systems of the same arch where they are defined, and they cannot change.
115 * stone forever.
116 */
117
Jim Cownie181b4bb2013-12-23 17:28:57 +0000118# if KMP_ARCH_X86 || KMP_ARCH_ARM
Jim Cownie5e8470a2013-09-27 10:38:44 +0000119# ifndef __NR_sched_setaffinity
120# define __NR_sched_setaffinity 241
121# elif __NR_sched_setaffinity != 241
122# error Wrong code for setaffinity system call.
123# endif /* __NR_sched_setaffinity */
124# ifndef __NR_sched_getaffinity
125# define __NR_sched_getaffinity 242
126# elif __NR_sched_getaffinity != 242
127# error Wrong code for getaffinity system call.
128# endif /* __NR_sched_getaffinity */
129
Andrey Churbanovcbda8682015-01-13 14:43:35 +0000130# elif KMP_ARCH_AARCH64
131# ifndef __NR_sched_setaffinity
132# define __NR_sched_setaffinity 122
133# elif __NR_sched_setaffinity != 122
134# error Wrong code for setaffinity system call.
135# endif /* __NR_sched_setaffinity */
136# ifndef __NR_sched_getaffinity
137# define __NR_sched_getaffinity 123
138# elif __NR_sched_getaffinity != 123
139# error Wrong code for getaffinity system call.
140# endif /* __NR_sched_getaffinity */
141
Jim Cownie5e8470a2013-09-27 10:38:44 +0000142# elif KMP_ARCH_X86_64
143# ifndef __NR_sched_setaffinity
144# define __NR_sched_setaffinity 203
145# elif __NR_sched_setaffinity != 203
146# error Wrong code for setaffinity system call.
147# endif /* __NR_sched_setaffinity */
148# ifndef __NR_sched_getaffinity
149# define __NR_sched_getaffinity 204
150# elif __NR_sched_getaffinity != 204
151# error Wrong code for getaffinity system call.
152# endif /* __NR_sched_getaffinity */
153
Jim Cownie3051f972014-08-07 10:12:54 +0000154# elif KMP_ARCH_PPC64
155# ifndef __NR_sched_setaffinity
156# define __NR_sched_setaffinity 222
157# elif __NR_sched_setaffinity != 222
158# error Wrong code for setaffinity system call.
159# endif /* __NR_sched_setaffinity */
160# ifndef __NR_sched_getaffinity
161# define __NR_sched_getaffinity 223
162# elif __NR_sched_getaffinity != 223
163# error Wrong code for getaffinity system call.
164# endif /* __NR_sched_getaffinity */
165
166
Jim Cownie5e8470a2013-09-27 10:38:44 +0000167# else
168# error Unknown or unsupported architecture
169
170# endif /* KMP_ARCH_* */
171
172int
173__kmp_set_system_affinity( kmp_affin_mask_t const *mask, int abort_on_error )
174{
175 KMP_ASSERT2(KMP_AFFINITY_CAPABLE(),
176 "Illegal set affinity operation when not capable");
Jonathan Peyton01dcf362015-11-30 20:02:59 +0000177#if KMP_USE_HWLOC
178 int retval = hwloc_set_cpubind(__kmp_hwloc_topology, (hwloc_cpuset_t)mask, HWLOC_CPUBIND_THREAD);
179#else
Jim Cownie5e8470a2013-09-27 10:38:44 +0000180 int retval = syscall( __NR_sched_setaffinity, 0, __kmp_affin_mask_size, mask );
Jonathan Peyton01dcf362015-11-30 20:02:59 +0000181#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +0000182 if (retval >= 0) {
183 return 0;
184 }
185 int error = errno;
186 if (abort_on_error) {
187 __kmp_msg(
188 kmp_ms_fatal,
189 KMP_MSG( FatalSysError ),
190 KMP_ERR( error ),
191 __kmp_msg_null
192 );
193 }
194 return error;
195}
196
197int
198__kmp_get_system_affinity( kmp_affin_mask_t *mask, int abort_on_error )
199{
200 KMP_ASSERT2(KMP_AFFINITY_CAPABLE(),
201 "Illegal get affinity operation when not capable");
202
Jonathan Peyton01dcf362015-11-30 20:02:59 +0000203#if KMP_USE_HWLOC
204 int retval = hwloc_get_cpubind(__kmp_hwloc_topology, (hwloc_cpuset_t)mask, HWLOC_CPUBIND_THREAD);
205#else
Jim Cownie5e8470a2013-09-27 10:38:44 +0000206 int retval = syscall( __NR_sched_getaffinity, 0, __kmp_affin_mask_size, mask );
Jonathan Peyton01dcf362015-11-30 20:02:59 +0000207#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +0000208 if (retval >= 0) {
209 return 0;
210 }
211 int error = errno;
212 if (abort_on_error) {
213 __kmp_msg(
214 kmp_ms_fatal,
215 KMP_MSG( FatalSysError ),
216 KMP_ERR( error ),
217 __kmp_msg_null
218 );
219 }
220 return error;
221}
222
223void
224__kmp_affinity_bind_thread( int which )
225{
226 KMP_ASSERT2(KMP_AFFINITY_CAPABLE(),
227 "Illegal set affinity operation when not capable");
228
Jonathan Peyton01dcf362015-11-30 20:02:59 +0000229 kmp_affin_mask_t *mask;
230 KMP_CPU_ALLOC_ON_STACK(mask);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000231 KMP_CPU_ZERO(mask);
232 KMP_CPU_SET(which, mask);
233 __kmp_set_system_affinity(mask, TRUE);
Jonathan Peyton01dcf362015-11-30 20:02:59 +0000234 KMP_CPU_FREE_FROM_STACK(mask);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000235}
236
237/*
238 * Determine if we can access affinity functionality on this version of
239 * Linux* OS by checking __NR_sched_{get,set}affinity system calls, and set
240 * __kmp_affin_mask_size to the appropriate value (0 means not capable).
241 */
242void
243__kmp_affinity_determine_capable(const char *env_var)
244{
245 //
246 // Check and see if the OS supports thread affinity.
247 //
248
249# define KMP_CPU_SET_SIZE_LIMIT (1024*1024)
250
251 int gCode;
252 int sCode;
253 kmp_affin_mask_t *buf;
254 buf = ( kmp_affin_mask_t * ) KMP_INTERNAL_MALLOC( KMP_CPU_SET_SIZE_LIMIT );
255
256 // If Linux* OS:
257 // If the syscall fails or returns a suggestion for the size,
258 // then we don't have to search for an appropriate size.
259 gCode = syscall( __NR_sched_getaffinity, 0, KMP_CPU_SET_SIZE_LIMIT, buf );
260 KA_TRACE(30, ( "__kmp_affinity_determine_capable: "
Alp Toker8f2d3f02014-02-24 10:40:15 +0000261 "initial getaffinity call returned %d errno = %d\n",
Jim Cownie5e8470a2013-09-27 10:38:44 +0000262 gCode, errno));
263
264 //if ((gCode < 0) && (errno == ENOSYS))
265 if (gCode < 0) {
266 //
267 // System call not supported
268 //
269 if (__kmp_affinity_verbose || (__kmp_affinity_warnings
270 && (__kmp_affinity_type != affinity_none)
271 && (__kmp_affinity_type != affinity_default)
272 && (__kmp_affinity_type != affinity_disabled))) {
273 int error = errno;
274 __kmp_msg(
275 kmp_ms_warning,
276 KMP_MSG( GetAffSysCallNotSupported, env_var ),
277 KMP_ERR( error ),
278 __kmp_msg_null
279 );
280 }
Andrey Churbanov1f037e42015-03-10 09:15:26 +0000281 KMP_AFFINITY_DISABLE();
Jim Cownie5e8470a2013-09-27 10:38:44 +0000282 KMP_INTERNAL_FREE(buf);
283 return;
284 }
285 if (gCode > 0) { // Linux* OS only
286 // The optimal situation: the OS returns the size of the buffer
287 // it expects.
288 //
289 // A verification of correct behavior is that Isetaffinity on a NULL
290 // buffer with the same size fails with errno set to EFAULT.
291 sCode = syscall( __NR_sched_setaffinity, 0, gCode, NULL );
292 KA_TRACE(30, ( "__kmp_affinity_determine_capable: "
293 "setaffinity for mask size %d returned %d errno = %d\n",
294 gCode, sCode, errno));
295 if (sCode < 0) {
296 if (errno == ENOSYS) {
297 if (__kmp_affinity_verbose || (__kmp_affinity_warnings
298 && (__kmp_affinity_type != affinity_none)
299 && (__kmp_affinity_type != affinity_default)
300 && (__kmp_affinity_type != affinity_disabled))) {
301 int error = errno;
302 __kmp_msg(
303 kmp_ms_warning,
304 KMP_MSG( SetAffSysCallNotSupported, env_var ),
305 KMP_ERR( error ),
306 __kmp_msg_null
307 );
308 }
Andrey Churbanov1f037e42015-03-10 09:15:26 +0000309 KMP_AFFINITY_DISABLE();
Jim Cownie5e8470a2013-09-27 10:38:44 +0000310 KMP_INTERNAL_FREE(buf);
311 }
312 if (errno == EFAULT) {
Andrey Churbanov1f037e42015-03-10 09:15:26 +0000313 KMP_AFFINITY_ENABLE(gCode);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000314 KA_TRACE(10, ( "__kmp_affinity_determine_capable: "
315 "affinity supported (mask size %d)\n",
316 (int)__kmp_affin_mask_size));
317 KMP_INTERNAL_FREE(buf);
318 return;
319 }
320 }
321 }
322
323 //
324 // Call the getaffinity system call repeatedly with increasing set sizes
325 // until we succeed, or reach an upper bound on the search.
326 //
327 KA_TRACE(30, ( "__kmp_affinity_determine_capable: "
328 "searching for proper set size\n"));
329 int size;
330 for (size = 1; size <= KMP_CPU_SET_SIZE_LIMIT; size *= 2) {
331 gCode = syscall( __NR_sched_getaffinity, 0, size, buf );
332 KA_TRACE(30, ( "__kmp_affinity_determine_capable: "
333 "getaffinity for mask size %d returned %d errno = %d\n", size,
334 gCode, errno));
335
336 if (gCode < 0) {
337 if ( errno == ENOSYS )
338 {
339 //
340 // We shouldn't get here
341 //
342 KA_TRACE(30, ( "__kmp_affinity_determine_capable: "
343 "inconsistent OS call behavior: errno == ENOSYS for mask size %d\n",
344 size));
345 if (__kmp_affinity_verbose || (__kmp_affinity_warnings
346 && (__kmp_affinity_type != affinity_none)
347 && (__kmp_affinity_type != affinity_default)
348 && (__kmp_affinity_type != affinity_disabled))) {
349 int error = errno;
350 __kmp_msg(
351 kmp_ms_warning,
352 KMP_MSG( GetAffSysCallNotSupported, env_var ),
353 KMP_ERR( error ),
354 __kmp_msg_null
355 );
356 }
Andrey Churbanov1f037e42015-03-10 09:15:26 +0000357 KMP_AFFINITY_DISABLE();
Jim Cownie5e8470a2013-09-27 10:38:44 +0000358 KMP_INTERNAL_FREE(buf);
359 return;
360 }
361 continue;
362 }
363
364 sCode = syscall( __NR_sched_setaffinity, 0, gCode, NULL );
365 KA_TRACE(30, ( "__kmp_affinity_determine_capable: "
366 "setaffinity for mask size %d returned %d errno = %d\n",
367 gCode, sCode, errno));
368 if (sCode < 0) {
369 if (errno == ENOSYS) { // Linux* OS only
370 //
371 // We shouldn't get here
372 //
373 KA_TRACE(30, ( "__kmp_affinity_determine_capable: "
374 "inconsistent OS call behavior: errno == ENOSYS for mask size %d\n",
375 size));
376 if (__kmp_affinity_verbose || (__kmp_affinity_warnings
377 && (__kmp_affinity_type != affinity_none)
378 && (__kmp_affinity_type != affinity_default)
379 && (__kmp_affinity_type != affinity_disabled))) {
380 int error = errno;
381 __kmp_msg(
382 kmp_ms_warning,
383 KMP_MSG( SetAffSysCallNotSupported, env_var ),
384 KMP_ERR( error ),
385 __kmp_msg_null
386 );
387 }
Andrey Churbanov1f037e42015-03-10 09:15:26 +0000388 KMP_AFFINITY_DISABLE();
Jim Cownie5e8470a2013-09-27 10:38:44 +0000389 KMP_INTERNAL_FREE(buf);
390 return;
391 }
392 if (errno == EFAULT) {
Andrey Churbanov1f037e42015-03-10 09:15:26 +0000393 KMP_AFFINITY_ENABLE(gCode);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000394 KA_TRACE(10, ( "__kmp_affinity_determine_capable: "
395 "affinity supported (mask size %d)\n",
396 (int)__kmp_affin_mask_size));
397 KMP_INTERNAL_FREE(buf);
398 return;
399 }
400 }
401 }
402 //int error = errno; // save uncaught error code
403 KMP_INTERNAL_FREE(buf);
404 // errno = error; // restore uncaught error code, will be printed at the next KMP_WARNING below
405
406 //
407 // Affinity is not supported
408 //
Andrey Churbanov1f037e42015-03-10 09:15:26 +0000409 KMP_AFFINITY_DISABLE();
Jim Cownie5e8470a2013-09-27 10:38:44 +0000410 KA_TRACE(10, ( "__kmp_affinity_determine_capable: "
411 "cannot determine mask size - affinity not supported\n"));
412 if (__kmp_affinity_verbose || (__kmp_affinity_warnings
413 && (__kmp_affinity_type != affinity_none)
414 && (__kmp_affinity_type != affinity_default)
415 && (__kmp_affinity_type != affinity_disabled))) {
416 KMP_WARNING( AffCantGetMaskSize, env_var );
417 }
418}
419
Andrey Churbanovd39f11c2015-03-10 10:14:57 +0000420#endif // KMP_OS_LINUX && KMP_AFFINITY_SUPPORTED
Jim Cownie5e8470a2013-09-27 10:38:44 +0000421
Andrey Churbanovd39f11c2015-03-10 10:14:57 +0000422/* ------------------------------------------------------------------------ */
423/* ------------------------------------------------------------------------ */
424
425#if KMP_OS_LINUX && (KMP_ARCH_X86 || KMP_ARCH_X86_64 || KMP_ARCH_ARM || KMP_ARCH_AARCH64) && !KMP_OS_CNK
426
427int
428__kmp_futex_determine_capable()
429{
430 int loc = 0;
431 int rc = syscall( __NR_futex, &loc, FUTEX_WAKE, 1, NULL, NULL, 0 );
432 int retval = ( rc == 0 ) || ( errno != ENOSYS );
433
434 KA_TRACE(10, ( "__kmp_futex_determine_capable: rc = %d errno = %d\n", rc,
435 errno ) );
436 KA_TRACE(10, ( "__kmp_futex_determine_capable: futex syscall%s supported\n",
437 retval ? "" : " not" ) );
438
439 return retval;
440}
441
442#endif // KMP_OS_LINUX && (KMP_ARCH_X86 || KMP_ARCH_X86_64 || KMP_ARCH_ARM) && !KMP_OS_CNK
443
444/* ------------------------------------------------------------------------ */
445/* ------------------------------------------------------------------------ */
446
447#if (KMP_ARCH_X86 || KMP_ARCH_X86_64) && (! KMP_ASM_INTRINS)
Jim Cownie5e8470a2013-09-27 10:38:44 +0000448/*
Andrey Churbanovd39f11c2015-03-10 10:14:57 +0000449 * Only 32-bit "add-exchange" instruction on IA-32 architecture causes us to
450 * use compare_and_store for these routines
Jim Cownie5e8470a2013-09-27 10:38:44 +0000451 */
452
Andrey Churbanov7b2ab712015-03-10 09:03:42 +0000453kmp_int8
454__kmp_test_then_or8( volatile kmp_int8 *p, kmp_int8 d )
455{
456 kmp_int8 old_value, new_value;
457
458 old_value = TCR_1( *p );
459 new_value = old_value | d;
460
461 while ( ! KMP_COMPARE_AND_STORE_REL8 ( p, old_value, new_value ) )
462 {
463 KMP_CPU_PAUSE();
464 old_value = TCR_1( *p );
465 new_value = old_value | d;
466 }
467 return old_value;
468}
469
470kmp_int8
471__kmp_test_then_and8( volatile kmp_int8 *p, kmp_int8 d )
472{
473 kmp_int8 old_value, new_value;
474
475 old_value = TCR_1( *p );
476 new_value = old_value & d;
477
478 while ( ! KMP_COMPARE_AND_STORE_REL8 ( p, old_value, new_value ) )
479 {
480 KMP_CPU_PAUSE();
481 old_value = TCR_1( *p );
482 new_value = old_value & d;
483 }
484 return old_value;
485}
486
Jim Cownie5e8470a2013-09-27 10:38:44 +0000487kmp_int32
488__kmp_test_then_or32( volatile kmp_int32 *p, kmp_int32 d )
489{
490 kmp_int32 old_value, new_value;
491
492 old_value = TCR_4( *p );
493 new_value = old_value | d;
494
Jim Cownie3051f972014-08-07 10:12:54 +0000495 while ( ! KMP_COMPARE_AND_STORE_REL32 ( p, old_value, new_value ) )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000496 {
497 KMP_CPU_PAUSE();
498 old_value = TCR_4( *p );
499 new_value = old_value | d;
500 }
501 return old_value;
502}
503
504kmp_int32
505__kmp_test_then_and32( volatile kmp_int32 *p, kmp_int32 d )
506{
507 kmp_int32 old_value, new_value;
508
509 old_value = TCR_4( *p );
510 new_value = old_value & d;
511
Jim Cownie3051f972014-08-07 10:12:54 +0000512 while ( ! KMP_COMPARE_AND_STORE_REL32 ( p, old_value, new_value ) )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000513 {
514 KMP_CPU_PAUSE();
515 old_value = TCR_4( *p );
516 new_value = old_value & d;
517 }
518 return old_value;
519}
520
Andrey Churbanovcbda8682015-01-13 14:43:35 +0000521# if KMP_ARCH_X86 || KMP_ARCH_PPC64 || KMP_ARCH_AARCH64
Andrey Churbanovd39f11c2015-03-10 10:14:57 +0000522kmp_int8
523__kmp_test_then_add8( volatile kmp_int8 *p, kmp_int8 d )
524{
525 kmp_int8 old_value, new_value;
526
527 old_value = TCR_1( *p );
528 new_value = old_value + d;
529
530 while ( ! KMP_COMPARE_AND_STORE_REL8 ( p, old_value, new_value ) )
531 {
532 KMP_CPU_PAUSE();
533 old_value = TCR_1( *p );
534 new_value = old_value + d;
535 }
536 return old_value;
537}
538
Jim Cownie5e8470a2013-09-27 10:38:44 +0000539kmp_int64
540__kmp_test_then_add64( volatile kmp_int64 *p, kmp_int64 d )
541{
542 kmp_int64 old_value, new_value;
543
544 old_value = TCR_8( *p );
545 new_value = old_value + d;
546
Jim Cownie3051f972014-08-07 10:12:54 +0000547 while ( ! KMP_COMPARE_AND_STORE_REL64 ( p, old_value, new_value ) )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000548 {
549 KMP_CPU_PAUSE();
550 old_value = TCR_8( *p );
551 new_value = old_value + d;
552 }
553 return old_value;
554}
555# endif /* KMP_ARCH_X86 */
556
557kmp_int64
558__kmp_test_then_or64( volatile kmp_int64 *p, kmp_int64 d )
559{
560 kmp_int64 old_value, new_value;
561
562 old_value = TCR_8( *p );
563 new_value = old_value | d;
Jim Cownie3051f972014-08-07 10:12:54 +0000564 while ( ! KMP_COMPARE_AND_STORE_REL64 ( p, old_value, new_value ) )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000565 {
566 KMP_CPU_PAUSE();
567 old_value = TCR_8( *p );
568 new_value = old_value | d;
569 }
570 return old_value;
571}
572
573kmp_int64
574__kmp_test_then_and64( volatile kmp_int64 *p, kmp_int64 d )
575{
576 kmp_int64 old_value, new_value;
577
578 old_value = TCR_8( *p );
579 new_value = old_value & d;
Jim Cownie3051f972014-08-07 10:12:54 +0000580 while ( ! KMP_COMPARE_AND_STORE_REL64 ( p, old_value, new_value ) )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000581 {
582 KMP_CPU_PAUSE();
583 old_value = TCR_8( *p );
584 new_value = old_value & d;
585 }
586 return old_value;
587}
588
589#endif /* (KMP_ARCH_X86 || KMP_ARCH_X86_64) && (! KMP_ASM_INTRINS) */
590
591void
592__kmp_terminate_thread( int gtid )
593{
594 int status;
595 kmp_info_t *th = __kmp_threads[ gtid ];
596
597 if ( !th ) return;
598
599 #ifdef KMP_CANCEL_THREADS
600 KA_TRACE( 10, ("__kmp_terminate_thread: kill (%d)\n", gtid ) );
601 status = pthread_cancel( th->th.th_info.ds.ds_thread );
602 if ( status != 0 && status != ESRCH ) {
603 __kmp_msg(
604 kmp_ms_fatal,
605 KMP_MSG( CantTerminateWorkerThread ),
606 KMP_ERR( status ),
607 __kmp_msg_null
608 );
609 }; // if
610 #endif
611 __kmp_yield( TRUE );
612} //
613
614/* ------------------------------------------------------------------------ */
615/* ------------------------------------------------------------------------ */
616
617/* ------------------------------------------------------------------------ */
618/* ------------------------------------------------------------------------ */
619
620/*
621 * Set thread stack info according to values returned by
622 * pthread_getattr_np().
623 * If values are unreasonable, assume call failed and use
624 * incremental stack refinement method instead.
625 * Returns TRUE if the stack parameters could be determined exactly,
626 * FALSE if incremental refinement is necessary.
627 */
628static kmp_int32
629__kmp_set_stack_info( int gtid, kmp_info_t *th )
630{
631 int stack_data;
Joerg Sonnenberger1564f3c2015-09-21 20:02:45 +0000632#if KMP_OS_LINUX || KMP_OS_FREEBSD || KMP_OS_NETBSD
Jim Cownie5e8470a2013-09-27 10:38:44 +0000633 /* Linux* OS only -- no pthread_getattr_np support on OS X* */
634 pthread_attr_t attr;
635 int status;
636 size_t size = 0;
637 void * addr = 0;
638
639 /* Always do incremental stack refinement for ubermaster threads since the initial
640 thread stack range can be reduced by sibling thread creation so pthread_attr_getstack
641 may cause thread gtid aliasing */
642 if ( ! KMP_UBER_GTID(gtid) ) {
643
644 /* Fetch the real thread attributes */
645 status = pthread_attr_init( &attr );
646 KMP_CHECK_SYSFAIL( "pthread_attr_init", status );
Joerg Sonnenberger1564f3c2015-09-21 20:02:45 +0000647#if KMP_OS_FREEBSD || KMP_OS_NETBSD
Alp Toker763b9392014-02-28 09:42:41 +0000648 status = pthread_attr_get_np( pthread_self(), &attr );
649 KMP_CHECK_SYSFAIL( "pthread_attr_get_np", status );
650#else
Jim Cownie5e8470a2013-09-27 10:38:44 +0000651 status = pthread_getattr_np( pthread_self(), &attr );
652 KMP_CHECK_SYSFAIL( "pthread_getattr_np", status );
Alp Toker763b9392014-02-28 09:42:41 +0000653#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +0000654 status = pthread_attr_getstack( &attr, &addr, &size );
655 KMP_CHECK_SYSFAIL( "pthread_attr_getstack", status );
656 KA_TRACE( 60, ( "__kmp_set_stack_info: T#%d pthread_attr_getstack returned size: %lu, "
657 "low addr: %p\n",
658 gtid, size, addr ));
659
660 status = pthread_attr_destroy( &attr );
661 KMP_CHECK_SYSFAIL( "pthread_attr_destroy", status );
662 }
663
664 if ( size != 0 && addr != 0 ) { /* was stack parameter determination successful? */
665 /* Store the correct base and size */
666 TCW_PTR(th->th.th_info.ds.ds_stackbase, (((char *)addr) + size));
667 TCW_PTR(th->th.th_info.ds.ds_stacksize, size);
668 TCW_4(th->th.th_info.ds.ds_stackgrow, FALSE);
669 return TRUE;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000670 }
Joerg Sonnenberger1564f3c2015-09-21 20:02:45 +0000671#endif /* KMP_OS_LINUX || KMP_OS_FREEBSD || KMP_OS_NETBSD */
Alp Toker763b9392014-02-28 09:42:41 +0000672 /* Use incremental refinement starting from initial conservative estimate */
673 TCW_PTR(th->th.th_info.ds.ds_stacksize, 0);
674 TCW_PTR(th -> th.th_info.ds.ds_stackbase, &stack_data);
675 TCW_4(th->th.th_info.ds.ds_stackgrow, TRUE);
676 return FALSE;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000677}
678
679static void*
680__kmp_launch_worker( void *thr )
681{
682 int status, old_type, old_state;
683#ifdef KMP_BLOCK_SIGNALS
684 sigset_t new_set, old_set;
685#endif /* KMP_BLOCK_SIGNALS */
686 void *exit_val;
Joerg Sonnenberger1564f3c2015-09-21 20:02:45 +0000687#if KMP_OS_LINUX || KMP_OS_FREEBSD || KMP_OS_NETBSD
Andrey Churbanov368b70e2015-08-05 11:12:45 +0000688 void * volatile padding = 0;
Jonathan Peyton2321d572015-06-08 19:25:25 +0000689#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +0000690 int gtid;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000691
692 gtid = ((kmp_info_t*)thr) -> th.th_info.ds.ds_gtid;
693 __kmp_gtid_set_specific( gtid );
694#ifdef KMP_TDATA_GTID
695 __kmp_gtid = gtid;
696#endif
Jim Cownie4cc4bb42014-10-07 16:25:50 +0000697#if KMP_STATS_ENABLED
698 // set __thread local index to point to thread-specific stats
699 __kmp_stats_thread_ptr = ((kmp_info_t*)thr)->th.th_stats;
Jonathan Peyton11dc82f2016-05-05 16:15:57 +0000700 KMP_START_EXPLICIT_TIMER(OMP_worker_thread_life);
701 KMP_SET_THREAD_STATE(IDLE);
702 KMP_INIT_PARTITIONED_TIMERS(OMP_idle);
Jim Cownie4cc4bb42014-10-07 16:25:50 +0000703#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +0000704
705#if USE_ITT_BUILD
706 __kmp_itt_thread_name( gtid );
707#endif /* USE_ITT_BUILD */
708
Alp Toker763b9392014-02-28 09:42:41 +0000709#if KMP_AFFINITY_SUPPORTED
Jim Cownie5e8470a2013-09-27 10:38:44 +0000710 __kmp_affinity_set_init_mask( gtid, FALSE );
Jim Cownie5e8470a2013-09-27 10:38:44 +0000711#endif
712
713#ifdef KMP_CANCEL_THREADS
714 status = pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, & old_type );
715 KMP_CHECK_SYSFAIL( "pthread_setcanceltype", status );
716 /* josh todo: isn't PTHREAD_CANCEL_ENABLE default for newly-created threads? */
717 status = pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, & old_state );
718 KMP_CHECK_SYSFAIL( "pthread_setcancelstate", status );
719#endif
720
721#if KMP_ARCH_X86 || KMP_ARCH_X86_64
722 //
723 // Set the FP control regs to be a copy of
724 // the parallel initialization thread's.
725 //
726 __kmp_clear_x87_fpu_status_word();
727 __kmp_load_x87_fpu_control_word( &__kmp_init_x87_fpu_control_word );
728 __kmp_load_mxcsr( &__kmp_init_mxcsr );
729#endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
730
731#ifdef KMP_BLOCK_SIGNALS
732 status = sigfillset( & new_set );
733 KMP_CHECK_SYSFAIL_ERRNO( "sigfillset", status );
734 status = pthread_sigmask( SIG_BLOCK, & new_set, & old_set );
735 KMP_CHECK_SYSFAIL( "pthread_sigmask", status );
736#endif /* KMP_BLOCK_SIGNALS */
737
Joerg Sonnenberger1564f3c2015-09-21 20:02:45 +0000738#if KMP_OS_LINUX || KMP_OS_FREEBSD || KMP_OS_NETBSD
Jim Cownie5e8470a2013-09-27 10:38:44 +0000739 if ( __kmp_stkoffset > 0 && gtid > 0 ) {
Andrey Churbanov74bf17b2015-04-02 13:27:08 +0000740 padding = KMP_ALLOCA( gtid * __kmp_stkoffset );
Jim Cownie5e8470a2013-09-27 10:38:44 +0000741 }
742#endif
743
744 KMP_MB();
745 __kmp_set_stack_info( gtid, (kmp_info_t*)thr );
746
747 __kmp_check_stack_overlap( (kmp_info_t*)thr );
748
749 exit_val = __kmp_launch_thread( (kmp_info_t *) thr );
750
751#ifdef KMP_BLOCK_SIGNALS
752 status = pthread_sigmask( SIG_SETMASK, & old_set, NULL );
753 KMP_CHECK_SYSFAIL( "pthread_sigmask", status );
754#endif /* KMP_BLOCK_SIGNALS */
755
756 return exit_val;
757}
758
Jim Cownie5e8470a2013-09-27 10:38:44 +0000759/* The monitor thread controls all of the threads in the complex */
760
761static void*
762__kmp_launch_monitor( void *thr )
763{
764 int status, old_type, old_state;
765#ifdef KMP_BLOCK_SIGNALS
766 sigset_t new_set;
767#endif /* KMP_BLOCK_SIGNALS */
768 struct timespec interval;
769 int yield_count;
770 int yield_cycles = 0;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000771
772 KMP_MB(); /* Flush all pending memory write invalidates. */
773
774 KA_TRACE( 10, ("__kmp_launch_monitor: #1 launched\n" ) );
775
776 /* register us as the monitor thread */
777 __kmp_gtid_set_specific( KMP_GTID_MONITOR );
778#ifdef KMP_TDATA_GTID
779 __kmp_gtid = KMP_GTID_MONITOR;
780#endif
781
782 KMP_MB();
783
784#if USE_ITT_BUILD
785 __kmp_itt_thread_ignore(); // Instruct Intel(R) Threading Tools to ignore monitor thread.
786#endif /* USE_ITT_BUILD */
787
788 __kmp_set_stack_info( ((kmp_info_t*)thr)->th.th_info.ds.ds_gtid, (kmp_info_t*)thr );
789
790 __kmp_check_stack_overlap( (kmp_info_t*)thr );
791
792#ifdef KMP_CANCEL_THREADS
793 status = pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, & old_type );
794 KMP_CHECK_SYSFAIL( "pthread_setcanceltype", status );
795 /* josh todo: isn't PTHREAD_CANCEL_ENABLE default for newly-created threads? */
796 status = pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, & old_state );
797 KMP_CHECK_SYSFAIL( "pthread_setcancelstate", status );
798#endif
799
800 #if KMP_REAL_TIME_FIX
801 // This is a potential fix which allows application with real-time scheduling policy work.
802 // However, decision about the fix is not made yet, so it is disabled by default.
803 { // Are program started with real-time scheduling policy?
804 int sched = sched_getscheduler( 0 );
805 if ( sched == SCHED_FIFO || sched == SCHED_RR ) {
806 // Yes, we are a part of real-time application. Try to increase the priority of the
807 // monitor.
808 struct sched_param param;
809 int max_priority = sched_get_priority_max( sched );
810 int rc;
811 KMP_WARNING( RealTimeSchedNotSupported );
812 sched_getparam( 0, & param );
813 if ( param.sched_priority < max_priority ) {
814 param.sched_priority += 1;
815 rc = sched_setscheduler( 0, sched, & param );
816 if ( rc != 0 ) {
817 int error = errno;
818 __kmp_msg(
819 kmp_ms_warning,
820 KMP_MSG( CantChangeMonitorPriority ),
821 KMP_ERR( error ),
822 KMP_MSG( MonitorWillStarve ),
823 __kmp_msg_null
824 );
825 }; // if
826 } else {
827 // We cannot abort here, because number of CPUs may be enough for all the threads,
828 // including the monitor thread, so application could potentially work...
829 __kmp_msg(
830 kmp_ms_warning,
831 KMP_MSG( RunningAtMaxPriority ),
832 KMP_MSG( MonitorWillStarve ),
833 KMP_HNT( RunningAtMaxPriority ),
834 __kmp_msg_null
835 );
836 }; // if
837 }; // if
Jim Cownie4cc4bb42014-10-07 16:25:50 +0000838 TCW_4( __kmp_global.g.g_time.dt.t_value, 0 ); // AC: free thread that waits for monitor started
Jim Cownie5e8470a2013-09-27 10:38:44 +0000839 }
840 #endif // KMP_REAL_TIME_FIX
841
842 KMP_MB(); /* Flush all pending memory write invalidates. */
843
844 if ( __kmp_monitor_wakeups == 1 ) {
845 interval.tv_sec = 1;
846 interval.tv_nsec = 0;
847 } else {
848 interval.tv_sec = 0;
Jonathan Peyton1e7a1dd2015-06-04 17:29:13 +0000849 interval.tv_nsec = (KMP_NSEC_PER_SEC / __kmp_monitor_wakeups);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000850 }
851
852 KA_TRACE( 10, ("__kmp_launch_monitor: #2 monitor\n" ) );
853
854 if (__kmp_yield_cycle) {
855 __kmp_yielding_on = 0; /* Start out with yielding shut off */
856 yield_count = __kmp_yield_off_count;
857 } else {
858 __kmp_yielding_on = 1; /* Yielding is on permanently */
859 }
860
861 while( ! TCR_4( __kmp_global.g.g_done ) ) {
862 struct timespec now;
863 struct timeval tval;
864
865 /* This thread monitors the state of the system */
866
867 KA_TRACE( 15, ( "__kmp_launch_monitor: update\n" ) );
868
869 status = gettimeofday( &tval, NULL );
870 KMP_CHECK_SYSFAIL_ERRNO( "gettimeofday", status );
871 TIMEVAL_TO_TIMESPEC( &tval, &now );
872
873 now.tv_sec += interval.tv_sec;
874 now.tv_nsec += interval.tv_nsec;
875
Jonathan Peyton1e7a1dd2015-06-04 17:29:13 +0000876 if (now.tv_nsec >= KMP_NSEC_PER_SEC) {
Jim Cownie5e8470a2013-09-27 10:38:44 +0000877 now.tv_sec += 1;
Jonathan Peyton1e7a1dd2015-06-04 17:29:13 +0000878 now.tv_nsec -= KMP_NSEC_PER_SEC;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000879 }
880
881 status = pthread_mutex_lock( & __kmp_wait_mx.m_mutex );
882 KMP_CHECK_SYSFAIL( "pthread_mutex_lock", status );
Jim Cownie07ea89f2014-09-03 11:10:54 +0000883 // AC: the monitor should not fall asleep if g_done has been set
884 if ( !TCR_4(__kmp_global.g.g_done) ) { // check once more under mutex
885 status = pthread_cond_timedwait( &__kmp_wait_cv.c_cond, &__kmp_wait_mx.m_mutex, &now );
886 if ( status != 0 ) {
887 if ( status != ETIMEDOUT && status != EINTR ) {
888 KMP_SYSFAIL( "pthread_cond_timedwait", status );
889 };
Jim Cownie5e8470a2013-09-27 10:38:44 +0000890 };
891 };
Jim Cownie5e8470a2013-09-27 10:38:44 +0000892 status = pthread_mutex_unlock( & __kmp_wait_mx.m_mutex );
893 KMP_CHECK_SYSFAIL( "pthread_mutex_unlock", status );
894
895 if (__kmp_yield_cycle) {
896 yield_cycles++;
897 if ( (yield_cycles % yield_count) == 0 ) {
898 if (__kmp_yielding_on) {
899 __kmp_yielding_on = 0; /* Turn it off now */
900 yield_count = __kmp_yield_off_count;
901 } else {
902 __kmp_yielding_on = 1; /* Turn it on now */
903 yield_count = __kmp_yield_on_count;
904 }
905 yield_cycles = 0;
906 }
907 } else {
908 __kmp_yielding_on = 1;
909 }
910
911 TCW_4( __kmp_global.g.g_time.dt.t_value,
912 TCR_4( __kmp_global.g.g_time.dt.t_value ) + 1 );
913
914 KMP_MB(); /* Flush all pending memory write invalidates. */
915 }
916
917 KA_TRACE( 10, ("__kmp_launch_monitor: #3 cleanup\n" ) );
918
919#ifdef KMP_BLOCK_SIGNALS
920 status = sigfillset( & new_set );
921 KMP_CHECK_SYSFAIL_ERRNO( "sigfillset", status );
922 status = pthread_sigmask( SIG_UNBLOCK, & new_set, NULL );
923 KMP_CHECK_SYSFAIL( "pthread_sigmask", status );
924#endif /* KMP_BLOCK_SIGNALS */
925
926 KA_TRACE( 10, ("__kmp_launch_monitor: #4 finished\n" ) );
927
928 if( __kmp_global.g.g_abort != 0 ) {
929 /* now we need to terminate the worker threads */
930 /* the value of t_abort is the signal we caught */
931
932 int gtid;
933
934 KA_TRACE( 10, ("__kmp_launch_monitor: #5 terminate sig=%d\n", __kmp_global.g.g_abort ) );
935
936 /* terminate the OpenMP worker threads */
937 /* TODO this is not valid for sibling threads!!
938 * the uber master might not be 0 anymore.. */
939 for (gtid = 1; gtid < __kmp_threads_capacity; ++gtid)
940 __kmp_terminate_thread( gtid );
941
942 __kmp_cleanup();
943
944 KA_TRACE( 10, ("__kmp_launch_monitor: #6 raise sig=%d\n", __kmp_global.g.g_abort ) );
945
946 if (__kmp_global.g.g_abort > 0)
947 raise( __kmp_global.g.g_abort );
948
949 }
950
951 KA_TRACE( 10, ("__kmp_launch_monitor: #7 exit\n" ) );
952
953 return thr;
954}
955
956void
957__kmp_create_worker( int gtid, kmp_info_t *th, size_t stack_size )
958{
959 pthread_t handle;
960 pthread_attr_t thread_attr;
961 int status;
962
963
964 th->th.th_info.ds.ds_gtid = gtid;
965
Jim Cownie4cc4bb42014-10-07 16:25:50 +0000966#if KMP_STATS_ENABLED
967 // sets up worker thread stats
968 __kmp_acquire_tas_lock(&__kmp_stats_lock, gtid);
969
970 // th->th.th_stats is used to transfer thread specific stats-pointer to __kmp_launch_worker
971 // So when thread is created (goes into __kmp_launch_worker) it will
972 // set it's __thread local pointer to th->th.th_stats
973 th->th.th_stats = __kmp_stats_list.push_back(gtid);
974 if(KMP_UBER_GTID(gtid)) {
975 __kmp_stats_start_time = tsc_tick_count::now();
976 __kmp_stats_thread_ptr = th->th.th_stats;
977 __kmp_stats_init();
Jonathan Peyton11dc82f2016-05-05 16:15:57 +0000978 KMP_START_EXPLICIT_TIMER(OMP_worker_thread_life);
979 KMP_SET_THREAD_STATE(SERIAL_REGION);
980 KMP_INIT_PARTITIONED_TIMERS(OMP_serial);
Jim Cownie4cc4bb42014-10-07 16:25:50 +0000981 }
982 __kmp_release_tas_lock(&__kmp_stats_lock, gtid);
983
984#endif // KMP_STATS_ENABLED
985
Jim Cownie5e8470a2013-09-27 10:38:44 +0000986 if ( KMP_UBER_GTID(gtid) ) {
987 KA_TRACE( 10, ("__kmp_create_worker: uber thread (%d)\n", gtid ) );
988 th -> th.th_info.ds.ds_thread = pthread_self();
989 __kmp_set_stack_info( gtid, th );
990 __kmp_check_stack_overlap( th );
991 return;
992 }; // if
993
994 KA_TRACE( 10, ("__kmp_create_worker: try to create thread (%d)\n", gtid ) );
995
996 KMP_MB(); /* Flush all pending memory write invalidates. */
997
998#ifdef KMP_THREAD_ATTR
Jonathan Peyton749b4d52016-01-27 21:02:04 +0000999 status = pthread_attr_init( &thread_attr );
1000 if ( status != 0 ) {
1001 __kmp_msg(kmp_ms_fatal, KMP_MSG( CantInitThreadAttrs ), KMP_ERR( status ), __kmp_msg_null);
1002 }; // if
1003 status = pthread_attr_setdetachstate( & thread_attr, PTHREAD_CREATE_JOINABLE );
1004 if ( status != 0 ) {
1005 __kmp_msg(kmp_ms_fatal, KMP_MSG( CantSetWorkerState ), KMP_ERR( status ), __kmp_msg_null);
1006 }; // if
Jim Cownie5e8470a2013-09-27 10:38:44 +00001007
Jonathan Peyton749b4d52016-01-27 21:02:04 +00001008 /* Set stack size for this thread now.
1009 * The multiple of 2 is there because on some machines, requesting an unusual stacksize
1010 * causes the thread to have an offset before the dummy alloca() takes place to create the
1011 * offset. Since we want the user to have a sufficient stacksize AND support a stack offset, we
1012 * alloca() twice the offset so that the upcoming alloca() does not eliminate any premade
1013 * offset, and also gives the user the stack space they requested for all threads */
1014 stack_size += gtid * __kmp_stkoffset * 2;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001015
Jonathan Peyton749b4d52016-01-27 21:02:04 +00001016 KA_TRACE( 10, ( "__kmp_create_worker: T#%d, default stacksize = %lu bytes, "
1017 "__kmp_stksize = %lu bytes, final stacksize = %lu bytes\n",
1018 gtid, KMP_DEFAULT_STKSIZE, __kmp_stksize, stack_size ) );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001019
1020# ifdef _POSIX_THREAD_ATTR_STACKSIZE
Jonathan Peyton749b4d52016-01-27 21:02:04 +00001021 status = pthread_attr_setstacksize( & thread_attr, stack_size );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001022# ifdef KMP_BACKUP_STKSIZE
Jonathan Peyton749b4d52016-01-27 21:02:04 +00001023 if ( status != 0 ) {
1024 if ( ! __kmp_env_stksize ) {
1025 stack_size = KMP_BACKUP_STKSIZE + gtid * __kmp_stkoffset;
1026 __kmp_stksize = KMP_BACKUP_STKSIZE;
1027 KA_TRACE( 10, ("__kmp_create_worker: T#%d, default stacksize = %lu bytes, "
1028 "__kmp_stksize = %lu bytes, (backup) final stacksize = %lu "
1029 "bytes\n",
1030 gtid, KMP_DEFAULT_STKSIZE, __kmp_stksize, stack_size )
1031 );
1032 status = pthread_attr_setstacksize( &thread_attr, stack_size );
1033 }; // if
1034 }; // if
Jim Cownie5e8470a2013-09-27 10:38:44 +00001035# endif /* KMP_BACKUP_STKSIZE */
Jonathan Peyton749b4d52016-01-27 21:02:04 +00001036 if ( status != 0 ) {
1037 __kmp_msg(kmp_ms_fatal, KMP_MSG( CantSetWorkerStackSize, stack_size ), KMP_ERR( status ),
1038 KMP_HNT( ChangeWorkerStackSize ), __kmp_msg_null);
1039 }; // if
Jim Cownie5e8470a2013-09-27 10:38:44 +00001040# endif /* _POSIX_THREAD_ATTR_STACKSIZE */
Jonathan Peyton749b4d52016-01-27 21:02:04 +00001041
Jim Cownie5e8470a2013-09-27 10:38:44 +00001042#endif /* KMP_THREAD_ATTR */
1043
Jonathan Peyton749b4d52016-01-27 21:02:04 +00001044 status = pthread_create( & handle, & thread_attr, __kmp_launch_worker, (void *) th );
1045 if ( status != 0 || ! handle ) { // ??? Why do we check handle??
Jim Cownie5e8470a2013-09-27 10:38:44 +00001046#ifdef _POSIX_THREAD_ATTR_STACKSIZE
Jonathan Peyton749b4d52016-01-27 21:02:04 +00001047 if ( status == EINVAL ) {
1048 __kmp_msg(kmp_ms_fatal, KMP_MSG( CantSetWorkerStackSize, stack_size ), KMP_ERR( status ),
1049 KMP_HNT( IncreaseWorkerStackSize ), __kmp_msg_null);
1050 };
1051 if ( status == ENOMEM ) {
1052 __kmp_msg(kmp_ms_fatal, KMP_MSG( CantSetWorkerStackSize, stack_size ), KMP_ERR( status ),
1053 KMP_HNT( DecreaseWorkerStackSize ), __kmp_msg_null);
1054 };
Jim Cownie5e8470a2013-09-27 10:38:44 +00001055#endif /* _POSIX_THREAD_ATTR_STACKSIZE */
Jonathan Peyton749b4d52016-01-27 21:02:04 +00001056 if ( status == EAGAIN ) {
1057 __kmp_msg(kmp_ms_fatal, KMP_MSG( NoResourcesForWorkerThread ), KMP_ERR( status ),
1058 KMP_HNT( Decrease_NUM_THREADS ), __kmp_msg_null);
1059 }; // if
1060 KMP_SYSFAIL( "pthread_create", status );
1061 }; // if
Jim Cownie5e8470a2013-09-27 10:38:44 +00001062
Jonathan Peyton749b4d52016-01-27 21:02:04 +00001063 th->th.th_info.ds.ds_thread = handle;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001064
1065#ifdef KMP_THREAD_ATTR
Jonathan Peyton749b4d52016-01-27 21:02:04 +00001066 status = pthread_attr_destroy( & thread_attr );
1067 if ( status ) {
1068 __kmp_msg(kmp_ms_warning, KMP_MSG( CantDestroyThreadAttrs ), KMP_ERR( status ), __kmp_msg_null);
1069 }; // if
Jim Cownie5e8470a2013-09-27 10:38:44 +00001070#endif /* KMP_THREAD_ATTR */
1071
1072 KMP_MB(); /* Flush all pending memory write invalidates. */
1073
1074 KA_TRACE( 10, ("__kmp_create_worker: done creating thread (%d)\n", gtid ) );
1075
1076} // __kmp_create_worker
1077
1078
1079void
1080__kmp_create_monitor( kmp_info_t *th )
1081{
1082 pthread_t handle;
1083 pthread_attr_t thread_attr;
1084 size_t size;
1085 int status;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001086 int auto_adj_size = FALSE;
1087
Jonathan Peyton4fee5f62015-12-18 23:20:36 +00001088 if( __kmp_dflt_blocktime == KMP_MAX_BLOCKTIME ) {
1089 // We don't need monitor thread in case of MAX_BLOCKTIME
1090 KA_TRACE( 10, ("__kmp_create_monitor: skipping monitor thread because of MAX blocktime\n" ) );
1091 th->th.th_info.ds.ds_tid = 0; // this makes reap_monitor no-op
1092 th->th.th_info.ds.ds_gtid = 0;
1093 return;
1094 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00001095 KA_TRACE( 10, ("__kmp_create_monitor: try to create monitor\n" ) );
1096
1097 KMP_MB(); /* Flush all pending memory write invalidates. */
1098
1099 th->th.th_info.ds.ds_tid = KMP_GTID_MONITOR;
1100 th->th.th_info.ds.ds_gtid = KMP_GTID_MONITOR;
1101 #if KMP_REAL_TIME_FIX
1102 TCW_4( __kmp_global.g.g_time.dt.t_value, -1 ); // Will use it for synchronization a bit later.
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001103 #else
1104 TCW_4( __kmp_global.g.g_time.dt.t_value, 0 );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001105 #endif // KMP_REAL_TIME_FIX
1106
1107 #ifdef KMP_THREAD_ATTR
1108 if ( __kmp_monitor_stksize == 0 ) {
1109 __kmp_monitor_stksize = KMP_DEFAULT_MONITOR_STKSIZE;
1110 auto_adj_size = TRUE;
1111 }
1112 status = pthread_attr_init( &thread_attr );
1113 if ( status != 0 ) {
1114 __kmp_msg(
1115 kmp_ms_fatal,
1116 KMP_MSG( CantInitThreadAttrs ),
1117 KMP_ERR( status ),
1118 __kmp_msg_null
1119 );
1120 }; // if
1121 status = pthread_attr_setdetachstate( & thread_attr, PTHREAD_CREATE_JOINABLE );
1122 if ( status != 0 ) {
1123 __kmp_msg(
1124 kmp_ms_fatal,
1125 KMP_MSG( CantSetMonitorState ),
1126 KMP_ERR( status ),
1127 __kmp_msg_null
1128 );
1129 }; // if
1130
1131 #ifdef _POSIX_THREAD_ATTR_STACKSIZE
1132 status = pthread_attr_getstacksize( & thread_attr, & size );
1133 KMP_CHECK_SYSFAIL( "pthread_attr_getstacksize", status );
1134 #else
1135 size = __kmp_sys_min_stksize;
1136 #endif /* _POSIX_THREAD_ATTR_STACKSIZE */
1137 #endif /* KMP_THREAD_ATTR */
1138
1139 if ( __kmp_monitor_stksize == 0 ) {
1140 __kmp_monitor_stksize = KMP_DEFAULT_MONITOR_STKSIZE;
1141 }
1142 if ( __kmp_monitor_stksize < __kmp_sys_min_stksize ) {
1143 __kmp_monitor_stksize = __kmp_sys_min_stksize;
1144 }
1145
1146 KA_TRACE( 10, ( "__kmp_create_monitor: default stacksize = %lu bytes,"
1147 "requested stacksize = %lu bytes\n",
1148 size, __kmp_monitor_stksize ) );
1149
1150 retry:
1151
1152 /* Set stack size for this thread now. */
1153
1154 #ifdef _POSIX_THREAD_ATTR_STACKSIZE
1155 KA_TRACE( 10, ( "__kmp_create_monitor: setting stacksize = %lu bytes,",
1156 __kmp_monitor_stksize ) );
1157 status = pthread_attr_setstacksize( & thread_attr, __kmp_monitor_stksize );
1158 if ( status != 0 ) {
1159 if ( auto_adj_size ) {
1160 __kmp_monitor_stksize *= 2;
1161 goto retry;
1162 }
1163 __kmp_msg(
1164 kmp_ms_warning, // should this be fatal? BB
1165 KMP_MSG( CantSetMonitorStackSize, (long int) __kmp_monitor_stksize ),
1166 KMP_ERR( status ),
1167 KMP_HNT( ChangeMonitorStackSize ),
1168 __kmp_msg_null
1169 );
1170 }; // if
1171 #endif /* _POSIX_THREAD_ATTR_STACKSIZE */
1172
Jim Cownie5e8470a2013-09-27 10:38:44 +00001173 status = pthread_create( &handle, & thread_attr, __kmp_launch_monitor, (void *) th );
1174
1175 if ( status != 0 ) {
1176 #ifdef _POSIX_THREAD_ATTR_STACKSIZE
1177 if ( status == EINVAL ) {
1178 if ( auto_adj_size && ( __kmp_monitor_stksize < (size_t)0x40000000 ) ) {
1179 __kmp_monitor_stksize *= 2;
1180 goto retry;
1181 }
1182 __kmp_msg(
1183 kmp_ms_fatal,
1184 KMP_MSG( CantSetMonitorStackSize, __kmp_monitor_stksize ),
1185 KMP_ERR( status ),
1186 KMP_HNT( IncreaseMonitorStackSize ),
1187 __kmp_msg_null
1188 );
1189 }; // if
1190 if ( status == ENOMEM ) {
1191 __kmp_msg(
1192 kmp_ms_fatal,
1193 KMP_MSG( CantSetMonitorStackSize, __kmp_monitor_stksize ),
1194 KMP_ERR( status ),
1195 KMP_HNT( DecreaseMonitorStackSize ),
1196 __kmp_msg_null
1197 );
1198 }; // if
1199 #endif /* _POSIX_THREAD_ATTR_STACKSIZE */
1200 if ( status == EAGAIN ) {
1201 __kmp_msg(
1202 kmp_ms_fatal,
1203 KMP_MSG( NoResourcesForMonitorThread ),
1204 KMP_ERR( status ),
1205 KMP_HNT( DecreaseNumberOfThreadsInUse ),
1206 __kmp_msg_null
1207 );
1208 }; // if
1209 KMP_SYSFAIL( "pthread_create", status );
1210 }; // if
1211
1212 th->th.th_info.ds.ds_thread = handle;
1213
1214 #if KMP_REAL_TIME_FIX
1215 // Wait for the monitor thread is really started and set its *priority*.
1216 KMP_DEBUG_ASSERT( sizeof( kmp_uint32 ) == sizeof( __kmp_global.g.g_time.dt.t_value ) );
1217 __kmp_wait_yield_4(
1218 (kmp_uint32 volatile *) & __kmp_global.g.g_time.dt.t_value, -1, & __kmp_neq_4, NULL
1219 );
1220 #endif // KMP_REAL_TIME_FIX
1221
1222 #ifdef KMP_THREAD_ATTR
1223 status = pthread_attr_destroy( & thread_attr );
1224 if ( status != 0 ) {
1225 __kmp_msg( //
1226 kmp_ms_warning,
1227 KMP_MSG( CantDestroyThreadAttrs ),
1228 KMP_ERR( status ),
1229 __kmp_msg_null
1230 );
1231 }; // if
1232 #endif
1233
1234 KMP_MB(); /* Flush all pending memory write invalidates. */
1235
1236 KA_TRACE( 10, ( "__kmp_create_monitor: monitor created %#.8lx\n", th->th.th_info.ds.ds_thread ) );
1237
1238} // __kmp_create_monitor
1239
1240void
1241__kmp_exit_thread(
1242 int exit_status
1243) {
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001244 pthread_exit( (void *)(intptr_t) exit_status );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001245} // __kmp_exit_thread
1246
Jim Cownie07ea89f2014-09-03 11:10:54 +00001247void __kmp_resume_monitor();
1248
Jim Cownie5e8470a2013-09-27 10:38:44 +00001249void
1250__kmp_reap_monitor( kmp_info_t *th )
1251{
Jonathan Peyton7c4d66d2015-06-08 20:01:14 +00001252 int status;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001253 void *exit_val;
1254
1255 KA_TRACE( 10, ("__kmp_reap_monitor: try to reap monitor thread with handle %#.8lx\n",
1256 th->th.th_info.ds.ds_thread ) );
1257
1258 // If monitor has been created, its tid and gtid should be KMP_GTID_MONITOR.
1259 // If both tid and gtid are 0, it means the monitor did not ever start.
1260 // If both tid and gtid are KMP_GTID_DNE, the monitor has been shut down.
1261 KMP_DEBUG_ASSERT( th->th.th_info.ds.ds_tid == th->th.th_info.ds.ds_gtid );
1262 if ( th->th.th_info.ds.ds_gtid != KMP_GTID_MONITOR ) {
Jonathan Peyton4fee5f62015-12-18 23:20:36 +00001263 KA_TRACE( 10, ("__kmp_reap_monitor: monitor did not start, returning\n") );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001264 return;
1265 }; // if
1266
1267 KMP_MB(); /* Flush all pending memory write invalidates. */
1268
1269
1270 /* First, check to see whether the monitor thread exists. This could prevent a hang,
1271 but if the monitor dies after the pthread_kill call and before the pthread_join
1272 call, it will still hang. */
1273
1274 status = pthread_kill( th->th.th_info.ds.ds_thread, 0 );
1275 if (status == ESRCH) {
1276
1277 KA_TRACE( 10, ("__kmp_reap_monitor: monitor does not exist, returning\n") );
1278
1279 } else
1280 {
Jim Cownie07ea89f2014-09-03 11:10:54 +00001281 __kmp_resume_monitor(); // Wake up the monitor thread
Jim Cownie5e8470a2013-09-27 10:38:44 +00001282 status = pthread_join( th->th.th_info.ds.ds_thread, & exit_val);
1283 if (exit_val != th) {
1284 __kmp_msg(
1285 kmp_ms_fatal,
1286 KMP_MSG( ReapMonitorError ),
1287 KMP_ERR( status ),
1288 __kmp_msg_null
1289 );
1290 }
1291 }
1292
1293 th->th.th_info.ds.ds_tid = KMP_GTID_DNE;
1294 th->th.th_info.ds.ds_gtid = KMP_GTID_DNE;
1295
1296 KA_TRACE( 10, ("__kmp_reap_monitor: done reaping monitor thread with handle %#.8lx\n",
1297 th->th.th_info.ds.ds_thread ) );
1298
1299 KMP_MB(); /* Flush all pending memory write invalidates. */
1300
1301}
1302
1303void
1304__kmp_reap_worker( kmp_info_t *th )
1305{
1306 int status;
1307 void *exit_val;
1308
1309 KMP_MB(); /* Flush all pending memory write invalidates. */
1310
1311 KA_TRACE( 10, ("__kmp_reap_worker: try to reap T#%d\n", th->th.th_info.ds.ds_gtid ) );
1312
1313 /* First, check to see whether the worker thread exists. This could prevent a hang,
1314 but if the worker dies after the pthread_kill call and before the pthread_join
1315 call, it will still hang. */
1316
Jonathan Peyton749b4d52016-01-27 21:02:04 +00001317 status = pthread_kill( th->th.th_info.ds.ds_thread, 0 );
1318 if (status == ESRCH) {
1319 KA_TRACE( 10, ("__kmp_reap_worker: worker T#%d does not exist, returning\n", th->th.th_info.ds.ds_gtid ) );
1320 }
1321 else {
1322 KA_TRACE( 10, ("__kmp_reap_worker: try to join with worker T#%d\n", th->th.th_info.ds.ds_gtid ) );
1323 status = pthread_join( th->th.th_info.ds.ds_thread, & exit_val);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001324#ifdef KMP_DEBUG
Jonathan Peyton749b4d52016-01-27 21:02:04 +00001325 /* Don't expose these to the user until we understand when they trigger */
1326 if ( status != 0 ) {
1327 __kmp_msg(kmp_ms_fatal, KMP_MSG( ReapWorkerError ), KMP_ERR( status ), __kmp_msg_null);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001328 }
Jonathan Peyton749b4d52016-01-27 21:02:04 +00001329 if ( exit_val != th ) {
1330 KA_TRACE( 10, ( "__kmp_reap_worker: worker T#%d did not reap properly, exit_val = %p\n",
1331 th->th.th_info.ds.ds_gtid, exit_val ) );
1332 }
1333#endif /* KMP_DEBUG */
1334 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00001335
1336 KA_TRACE( 10, ("__kmp_reap_worker: done reaping T#%d\n", th->th.th_info.ds.ds_gtid ) );
1337
1338 KMP_MB(); /* Flush all pending memory write invalidates. */
1339}
1340
1341
1342/* ------------------------------------------------------------------------ */
1343/* ------------------------------------------------------------------------ */
1344
1345#if KMP_HANDLE_SIGNALS
1346
1347
1348static void
1349__kmp_null_handler( int signo )
1350{
1351 // Do nothing, for doing SIG_IGN-type actions.
1352} // __kmp_null_handler
1353
1354
1355static void
1356__kmp_team_handler( int signo )
1357{
1358 if ( __kmp_global.g.g_abort == 0 ) {
1359 /* Stage 1 signal handler, let's shut down all of the threads */
1360 #ifdef KMP_DEBUG
1361 __kmp_debug_printf( "__kmp_team_handler: caught signal = %d\n", signo );
1362 #endif
1363 switch ( signo ) {
1364 case SIGHUP :
1365 case SIGINT :
1366 case SIGQUIT :
1367 case SIGILL :
1368 case SIGABRT :
1369 case SIGFPE :
1370 case SIGBUS :
1371 case SIGSEGV :
1372 #ifdef SIGSYS
1373 case SIGSYS :
1374 #endif
1375 case SIGTERM :
1376 if ( __kmp_debug_buf ) {
1377 __kmp_dump_debug_buffer( );
1378 }; // if
1379 KMP_MB(); // Flush all pending memory write invalidates.
1380 TCW_4( __kmp_global.g.g_abort, signo );
1381 KMP_MB(); // Flush all pending memory write invalidates.
1382 TCW_4( __kmp_global.g.g_done, TRUE );
1383 KMP_MB(); // Flush all pending memory write invalidates.
1384 break;
1385 default:
1386 #ifdef KMP_DEBUG
1387 __kmp_debug_printf( "__kmp_team_handler: unknown signal type" );
1388 #endif
1389 break;
1390 }; // switch
1391 }; // if
1392} // __kmp_team_handler
1393
1394
1395static
1396void __kmp_sigaction( int signum, const struct sigaction * act, struct sigaction * oldact ) {
1397 int rc = sigaction( signum, act, oldact );
1398 KMP_CHECK_SYSFAIL_ERRNO( "sigaction", rc );
1399}
1400
1401
1402static void
1403__kmp_install_one_handler( int sig, sig_func_t handler_func, int parallel_init )
1404{
1405 KMP_MB(); // Flush all pending memory write invalidates.
1406 KB_TRACE( 60, ( "__kmp_install_one_handler( %d, ..., %d )\n", sig, parallel_init ) );
1407 if ( parallel_init ) {
1408 struct sigaction new_action;
1409 struct sigaction old_action;
1410 new_action.sa_handler = handler_func;
1411 new_action.sa_flags = 0;
1412 sigfillset( & new_action.sa_mask );
1413 __kmp_sigaction( sig, & new_action, & old_action );
1414 if ( old_action.sa_handler == __kmp_sighldrs[ sig ].sa_handler ) {
1415 sigaddset( & __kmp_sigset, sig );
1416 } else {
1417 // Restore/keep user's handler if one previously installed.
1418 __kmp_sigaction( sig, & old_action, NULL );
1419 }; // if
1420 } else {
1421 // Save initial/system signal handlers to see if user handlers installed.
1422 __kmp_sigaction( sig, NULL, & __kmp_sighldrs[ sig ] );
1423 }; // if
1424 KMP_MB(); // Flush all pending memory write invalidates.
1425} // __kmp_install_one_handler
1426
1427
1428static void
1429__kmp_remove_one_handler( int sig )
1430{
1431 KB_TRACE( 60, ( "__kmp_remove_one_handler( %d )\n", sig ) );
1432 if ( sigismember( & __kmp_sigset, sig ) ) {
1433 struct sigaction old;
1434 KMP_MB(); // Flush all pending memory write invalidates.
1435 __kmp_sigaction( sig, & __kmp_sighldrs[ sig ], & old );
1436 if ( ( old.sa_handler != __kmp_team_handler ) && ( old.sa_handler != __kmp_null_handler ) ) {
1437 // Restore the users signal handler.
1438 KB_TRACE( 10, ( "__kmp_remove_one_handler: oops, not our handler, restoring: sig=%d\n", sig ) );
1439 __kmp_sigaction( sig, & old, NULL );
1440 }; // if
1441 sigdelset( & __kmp_sigset, sig );
1442 KMP_MB(); // Flush all pending memory write invalidates.
1443 }; // if
1444} // __kmp_remove_one_handler
1445
1446
1447void
1448__kmp_install_signals( int parallel_init )
1449{
1450 KB_TRACE( 10, ( "__kmp_install_signals( %d )\n", parallel_init ) );
1451 if ( __kmp_handle_signals || ! parallel_init ) {
1452 // If ! parallel_init, we do not install handlers, just save original handlers.
1453 // Let us do it even __handle_signals is 0.
1454 sigemptyset( & __kmp_sigset );
1455 __kmp_install_one_handler( SIGHUP, __kmp_team_handler, parallel_init );
1456 __kmp_install_one_handler( SIGINT, __kmp_team_handler, parallel_init );
1457 __kmp_install_one_handler( SIGQUIT, __kmp_team_handler, parallel_init );
1458 __kmp_install_one_handler( SIGILL, __kmp_team_handler, parallel_init );
1459 __kmp_install_one_handler( SIGABRT, __kmp_team_handler, parallel_init );
1460 __kmp_install_one_handler( SIGFPE, __kmp_team_handler, parallel_init );
1461 __kmp_install_one_handler( SIGBUS, __kmp_team_handler, parallel_init );
1462 __kmp_install_one_handler( SIGSEGV, __kmp_team_handler, parallel_init );
1463 #ifdef SIGSYS
1464 __kmp_install_one_handler( SIGSYS, __kmp_team_handler, parallel_init );
1465 #endif // SIGSYS
1466 __kmp_install_one_handler( SIGTERM, __kmp_team_handler, parallel_init );
1467 #ifdef SIGPIPE
1468 __kmp_install_one_handler( SIGPIPE, __kmp_team_handler, parallel_init );
1469 #endif // SIGPIPE
1470 }; // if
1471} // __kmp_install_signals
1472
1473
1474void
1475__kmp_remove_signals( void )
1476{
1477 int sig;
1478 KB_TRACE( 10, ( "__kmp_remove_signals()\n" ) );
1479 for ( sig = 1; sig < NSIG; ++ sig ) {
1480 __kmp_remove_one_handler( sig );
1481 }; // for sig
1482} // __kmp_remove_signals
1483
1484
1485#endif // KMP_HANDLE_SIGNALS
1486
1487/* ------------------------------------------------------------------------ */
1488/* ------------------------------------------------------------------------ */
1489
1490void
1491__kmp_enable( int new_state )
1492{
1493 #ifdef KMP_CANCEL_THREADS
1494 int status, old_state;
1495 status = pthread_setcancelstate( new_state, & old_state );
1496 KMP_CHECK_SYSFAIL( "pthread_setcancelstate", status );
1497 KMP_DEBUG_ASSERT( old_state == PTHREAD_CANCEL_DISABLE );
1498 #endif
1499}
1500
1501void
1502__kmp_disable( int * old_state )
1503{
1504 #ifdef KMP_CANCEL_THREADS
1505 int status;
1506 status = pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, old_state );
1507 KMP_CHECK_SYSFAIL( "pthread_setcancelstate", status );
1508 #endif
1509}
1510
1511/* ------------------------------------------------------------------------ */
1512/* ------------------------------------------------------------------------ */
1513
1514static void
1515__kmp_atfork_prepare (void)
1516{
1517 /* nothing to do */
1518}
1519
1520static void
1521__kmp_atfork_parent (void)
1522{
1523 /* nothing to do */
1524}
1525
1526/*
1527 Reset the library so execution in the child starts "all over again" with
1528 clean data structures in initial states. Don't worry about freeing memory
1529 allocated by parent, just abandon it to be safe.
1530*/
1531static void
1532__kmp_atfork_child (void)
1533{
1534 /* TODO make sure this is done right for nested/sibling */
1535 // ATT: Memory leaks are here? TODO: Check it and fix.
1536 /* KMP_ASSERT( 0 ); */
1537
1538 ++__kmp_fork_count;
1539
1540 __kmp_init_runtime = FALSE;
1541 __kmp_init_monitor = 0;
1542 __kmp_init_parallel = FALSE;
1543 __kmp_init_middle = FALSE;
1544 __kmp_init_serial = FALSE;
1545 TCW_4(__kmp_init_gtid, FALSE);
1546 __kmp_init_common = FALSE;
1547
1548 TCW_4(__kmp_init_user_locks, FALSE);
Andrey Churbanov5c56fb52015-02-20 18:05:17 +00001549#if ! KMP_USE_DYNAMIC_LOCK
Jim Cownie07ea89f2014-09-03 11:10:54 +00001550 __kmp_user_lock_table.used = 1;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001551 __kmp_user_lock_table.allocated = 0;
1552 __kmp_user_lock_table.table = NULL;
1553 __kmp_lock_blocks = NULL;
Andrey Churbanov5c56fb52015-02-20 18:05:17 +00001554#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +00001555
1556 __kmp_all_nth = 0;
1557 TCW_4(__kmp_nth, 0);
1558
1559 /* Must actually zero all the *cache arguments passed to __kmpc_threadprivate here
1560 so threadprivate doesn't use stale data */
1561 KA_TRACE( 10, ( "__kmp_atfork_child: checking cache address list %p\n",
1562 __kmp_threadpriv_cache_list ) );
1563
1564 while ( __kmp_threadpriv_cache_list != NULL ) {
1565
1566 if ( *__kmp_threadpriv_cache_list -> addr != NULL ) {
1567 KC_TRACE( 50, ( "__kmp_atfork_child: zeroing cache at address %p\n",
1568 &(*__kmp_threadpriv_cache_list -> addr) ) );
1569
1570 *__kmp_threadpriv_cache_list -> addr = NULL;
1571 }
1572 __kmp_threadpriv_cache_list = __kmp_threadpriv_cache_list -> next;
1573 }
1574
1575 __kmp_init_runtime = FALSE;
1576
1577 /* reset statically initialized locks */
1578 __kmp_init_bootstrap_lock( &__kmp_initz_lock );
1579 __kmp_init_bootstrap_lock( &__kmp_stdio_lock );
1580 __kmp_init_bootstrap_lock( &__kmp_console_lock );
1581
1582 /* This is necessary to make sure no stale data is left around */
1583 /* AC: customers complain that we use unsafe routines in the atfork
1584 handler. Mathworks: dlsym() is unsafe. We call dlsym and dlopen
1585 in dynamic_link when check the presence of shared tbbmalloc library.
1586 Suggestion is to make the library initialization lazier, similar
1587 to what done for __kmpc_begin(). */
1588 // TODO: synchronize all static initializations with regular library
1589 // startup; look at kmp_global.c and etc.
1590 //__kmp_internal_begin ();
1591
1592}
1593
1594void
1595__kmp_register_atfork(void) {
1596 if ( __kmp_need_register_atfork ) {
1597 int status = pthread_atfork( __kmp_atfork_prepare, __kmp_atfork_parent, __kmp_atfork_child );
1598 KMP_CHECK_SYSFAIL( "pthread_atfork", status );
1599 __kmp_need_register_atfork = FALSE;
1600 }
1601}
1602
1603void
1604__kmp_suspend_initialize( void )
1605{
1606 int status;
1607 status = pthread_mutexattr_init( &__kmp_suspend_mutex_attr );
1608 KMP_CHECK_SYSFAIL( "pthread_mutexattr_init", status );
1609 status = pthread_condattr_init( &__kmp_suspend_cond_attr );
1610 KMP_CHECK_SYSFAIL( "pthread_condattr_init", status );
1611}
1612
1613static void
1614__kmp_suspend_initialize_thread( kmp_info_t *th )
1615{
1616 if ( th->th.th_suspend_init_count <= __kmp_fork_count ) {
1617 /* this means we haven't initialized the suspension pthread objects for this thread
1618 in this instance of the process */
1619 int status;
1620 status = pthread_cond_init( &th->th.th_suspend_cv.c_cond, &__kmp_suspend_cond_attr );
1621 KMP_CHECK_SYSFAIL( "pthread_cond_init", status );
1622 status = pthread_mutex_init( &th->th.th_suspend_mx.m_mutex, & __kmp_suspend_mutex_attr );
1623 KMP_CHECK_SYSFAIL( "pthread_mutex_init", status );
1624 *(volatile int*)&th->th.th_suspend_init_count = __kmp_fork_count + 1;
1625 };
1626}
1627
1628void
1629__kmp_suspend_uninitialize_thread( kmp_info_t *th )
1630{
1631 if(th->th.th_suspend_init_count > __kmp_fork_count) {
1632 /* this means we have initialize the suspension pthread objects for this thread
1633 in this instance of the process */
1634 int status;
1635
1636 status = pthread_cond_destroy( &th->th.th_suspend_cv.c_cond );
1637 if ( status != 0 && status != EBUSY ) {
1638 KMP_SYSFAIL( "pthread_cond_destroy", status );
1639 };
1640 status = pthread_mutex_destroy( &th->th.th_suspend_mx.m_mutex );
1641 if ( status != 0 && status != EBUSY ) {
1642 KMP_SYSFAIL( "pthread_mutex_destroy", status );
1643 };
1644 --th->th.th_suspend_init_count;
1645 KMP_DEBUG_ASSERT(th->th.th_suspend_init_count == __kmp_fork_count);
1646 }
1647}
1648
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001649/* This routine puts the calling thread to sleep after setting the
1650 * sleep bit for the indicated flag variable to true.
Jim Cownie5e8470a2013-09-27 10:38:44 +00001651 */
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001652template <class C>
1653static inline void __kmp_suspend_template( int th_gtid, C *flag )
Jim Cownie5e8470a2013-09-27 10:38:44 +00001654{
Jonathan Peyton45be4502015-08-11 21:36:41 +00001655 KMP_TIME_DEVELOPER_BLOCK(USER_suspend);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001656 kmp_info_t *th = __kmp_threads[th_gtid];
1657 int status;
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001658 typename C::flag_t old_spin;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001659
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001660 KF_TRACE( 30, ("__kmp_suspend_template: T#%d enter for flag = %p\n", th_gtid, flag->get() ) );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001661
1662 __kmp_suspend_initialize_thread( th );
1663
1664 status = pthread_mutex_lock( &th->th.th_suspend_mx.m_mutex );
1665 KMP_CHECK_SYSFAIL( "pthread_mutex_lock", status );
1666
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001667 KF_TRACE( 10, ( "__kmp_suspend_template: T#%d setting sleep bit for spin(%p)\n",
1668 th_gtid, flag->get() ) );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001669
1670 /* TODO: shouldn't this use release semantics to ensure that __kmp_suspend_initialize_thread
1671 gets called first?
1672 */
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001673 old_spin = flag->set_sleeping();
Jim Cownie5e8470a2013-09-27 10:38:44 +00001674
Jonathan Peytone03b62f2015-10-08 18:49:40 +00001675 KF_TRACE( 5, ( "__kmp_suspend_template: T#%d set sleep bit for spin(%p)==%x, was %x\n",
1676 th_gtid, flag->get(), *(flag->get()), old_spin ) );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001677
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001678 if ( flag->done_check_val(old_spin) ) {
1679 old_spin = flag->unset_sleeping();
1680 KF_TRACE( 5, ( "__kmp_suspend_template: T#%d false alarm, reset sleep bit for spin(%p)\n",
1681 th_gtid, flag->get()) );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001682 } else {
Jim Cownie5e8470a2013-09-27 10:38:44 +00001683 /* Encapsulate in a loop as the documentation states that this may
1684 * "with low probability" return when the condition variable has
1685 * not been signaled or broadcast
1686 */
1687 int deactivated = FALSE;
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001688 TCW_PTR(th->th.th_sleep_loc, (void *)flag);
1689 while ( flag->is_sleeping() ) {
Jim Cownie5e8470a2013-09-27 10:38:44 +00001690#ifdef DEBUG_SUSPEND
1691 char buffer[128];
1692 __kmp_suspend_count++;
1693 __kmp_print_cond( buffer, &th->th.th_suspend_cv );
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001694 __kmp_printf( "__kmp_suspend_template: suspending T#%d: %s\n", th_gtid, buffer );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001695#endif
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001696 // Mark the thread as no longer active (only in the first iteration of the loop).
Jim Cownie5e8470a2013-09-27 10:38:44 +00001697 if ( ! deactivated ) {
1698 th->th.th_active = FALSE;
1699 if ( th->th.th_active_in_pool ) {
1700 th->th.th_active_in_pool = FALSE;
1701 KMP_TEST_THEN_DEC32(
1702 (kmp_int32 *) &__kmp_thread_pool_active_nth );
1703 KMP_DEBUG_ASSERT( TCR_4(__kmp_thread_pool_active_nth) >= 0 );
1704 }
1705 deactivated = TRUE;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001706 }
1707
1708#if USE_SUSPEND_TIMEOUT
1709 struct timespec now;
1710 struct timeval tval;
1711 int msecs;
1712
1713 status = gettimeofday( &tval, NULL );
1714 KMP_CHECK_SYSFAIL_ERRNO( "gettimeofday", status );
1715 TIMEVAL_TO_TIMESPEC( &tval, &now );
1716
1717 msecs = (4*__kmp_dflt_blocktime) + 200;
1718 now.tv_sec += msecs / 1000;
1719 now.tv_nsec += (msecs % 1000)*1000;
1720
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001721 KF_TRACE( 15, ( "__kmp_suspend_template: T#%d about to perform pthread_cond_timedwait\n",
Jim Cownie5e8470a2013-09-27 10:38:44 +00001722 th_gtid ) );
1723 status = pthread_cond_timedwait( &th->th.th_suspend_cv.c_cond, &th->th.th_suspend_mx.m_mutex, & now );
1724#else
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001725 KF_TRACE( 15, ( "__kmp_suspend_template: T#%d about to perform pthread_cond_wait\n",
Jonathan Peyton1bd61b42015-10-08 19:44:16 +00001726 th_gtid ) );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001727 status = pthread_cond_wait( &th->th.th_suspend_cv.c_cond, &th->th.th_suspend_mx.m_mutex );
1728#endif
1729
1730 if ( (status != 0) && (status != EINTR) && (status != ETIMEDOUT) ) {
1731 KMP_SYSFAIL( "pthread_cond_wait", status );
1732 }
1733#ifdef KMP_DEBUG
1734 if (status == ETIMEDOUT) {
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001735 if ( flag->is_sleeping() ) {
1736 KF_TRACE( 100, ( "__kmp_suspend_template: T#%d timeout wakeup\n", th_gtid ) );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001737 } else {
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001738 KF_TRACE( 2, ( "__kmp_suspend_template: T#%d timeout wakeup, sleep bit not set!\n",
Jim Cownie5e8470a2013-09-27 10:38:44 +00001739 th_gtid ) );
1740 }
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001741 } else if ( flag->is_sleeping() ) {
1742 KF_TRACE( 100, ( "__kmp_suspend_template: T#%d spurious wakeup\n", th_gtid ) );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001743 }
1744#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +00001745 } // while
1746
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001747 // Mark the thread as active again (if it was previous marked as inactive)
Jim Cownie5e8470a2013-09-27 10:38:44 +00001748 if ( deactivated ) {
1749 th->th.th_active = TRUE;
1750 if ( TCR_4(th->th.th_in_pool) ) {
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001751 KMP_TEST_THEN_INC32( (kmp_int32 *) &__kmp_thread_pool_active_nth );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001752 th->th.th_active_in_pool = TRUE;
1753 }
1754 }
1755 }
1756
1757#ifdef DEBUG_SUSPEND
1758 {
1759 char buffer[128];
1760 __kmp_print_cond( buffer, &th->th.th_suspend_cv);
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001761 __kmp_printf( "__kmp_suspend_template: T#%d has awakened: %s\n", th_gtid, buffer );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001762 }
1763#endif
1764
Jim Cownie5e8470a2013-09-27 10:38:44 +00001765 status = pthread_mutex_unlock( &th->th.th_suspend_mx.m_mutex );
1766 KMP_CHECK_SYSFAIL( "pthread_mutex_unlock", status );
1767
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001768 KF_TRACE( 30, ("__kmp_suspend_template: T#%d exit\n", th_gtid ) );
1769}
1770
1771void __kmp_suspend_32(int th_gtid, kmp_flag_32 *flag) {
1772 __kmp_suspend_template(th_gtid, flag);
1773}
1774void __kmp_suspend_64(int th_gtid, kmp_flag_64 *flag) {
1775 __kmp_suspend_template(th_gtid, flag);
1776}
1777void __kmp_suspend_oncore(int th_gtid, kmp_flag_oncore *flag) {
1778 __kmp_suspend_template(th_gtid, flag);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001779}
1780
1781
1782/* This routine signals the thread specified by target_gtid to wake up
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001783 * after setting the sleep bit indicated by the flag argument to FALSE.
1784 * The target thread must already have called __kmp_suspend_template()
Jim Cownie5e8470a2013-09-27 10:38:44 +00001785 */
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001786template <class C>
1787static inline void __kmp_resume_template( int target_gtid, C *flag )
Jim Cownie5e8470a2013-09-27 10:38:44 +00001788{
Jonathan Peyton45be4502015-08-11 21:36:41 +00001789 KMP_TIME_DEVELOPER_BLOCK(USER_resume);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001790 kmp_info_t *th = __kmp_threads[target_gtid];
1791 int status;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001792
1793#ifdef KMP_DEBUG
1794 int gtid = TCR_4(__kmp_init_gtid) ? __kmp_get_gtid() : -1;
1795#endif
1796
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001797 KF_TRACE( 30, ( "__kmp_resume_template: T#%d wants to wakeup T#%d enter\n", gtid, target_gtid ) );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001798 KMP_DEBUG_ASSERT( gtid != target_gtid );
1799
1800 __kmp_suspend_initialize_thread( th );
1801
1802 status = pthread_mutex_lock( &th->th.th_suspend_mx.m_mutex );
1803 KMP_CHECK_SYSFAIL( "pthread_mutex_lock", status );
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001804
Jonathan Peyton3f5dfc22015-11-09 16:31:51 +00001805 if (!flag) { // coming from __kmp_null_resume_wrapper
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001806 flag = (C *)th->th.th_sleep_loc;
1807 }
1808
Jonathan Peyton3f5dfc22015-11-09 16:31:51 +00001809 // First, check if the flag is null or its type has changed. If so, someone else woke it up.
1810 if (!flag || flag->get_type() != flag->get_ptr_type()) { // get_ptr_type simply shows what flag was cast to
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001811 KF_TRACE( 5, ( "__kmp_resume_template: T#%d exiting, thread T#%d already awake: flag(%p)\n",
1812 gtid, target_gtid, NULL ) );
1813 status = pthread_mutex_unlock( &th->th.th_suspend_mx.m_mutex );
1814 KMP_CHECK_SYSFAIL( "pthread_mutex_unlock", status );
1815 return;
1816 }
Jonathan Peyton1bd61b42015-10-08 19:44:16 +00001817 else { // if multiple threads are sleeping, flag should be internally referring to a specific thread here
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001818 typename C::flag_t old_spin = flag->unset_sleeping();
1819 if ( ! flag->is_sleeping_val(old_spin) ) {
1820 KF_TRACE( 5, ( "__kmp_resume_template: T#%d exiting, thread T#%d already awake: flag(%p): "
1821 "%u => %u\n",
1822 gtid, target_gtid, flag->get(), old_spin, *flag->get() ) );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001823 status = pthread_mutex_unlock( &th->th.th_suspend_mx.m_mutex );
1824 KMP_CHECK_SYSFAIL( "pthread_mutex_unlock", status );
1825 return;
1826 }
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001827 KF_TRACE( 5, ( "__kmp_resume_template: T#%d about to wakeup T#%d, reset sleep bit for flag's loc(%p): "
1828 "%u => %u\n",
1829 gtid, target_gtid, flag->get(), old_spin, *flag->get() ) );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001830 }
1831 TCW_PTR(th->th.th_sleep_loc, NULL);
1832
Jim Cownie5e8470a2013-09-27 10:38:44 +00001833
1834#ifdef DEBUG_SUSPEND
1835 {
1836 char buffer[128];
1837 __kmp_print_cond( buffer, &th->th.th_suspend_cv );
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001838 __kmp_printf( "__kmp_resume_template: T#%d resuming T#%d: %s\n", gtid, target_gtid, buffer );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001839 }
1840#endif
1841
Jim Cownie5e8470a2013-09-27 10:38:44 +00001842 status = pthread_cond_signal( &th->th.th_suspend_cv.c_cond );
1843 KMP_CHECK_SYSFAIL( "pthread_cond_signal", status );
1844 status = pthread_mutex_unlock( &th->th.th_suspend_mx.m_mutex );
1845 KMP_CHECK_SYSFAIL( "pthread_mutex_unlock", status );
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001846 KF_TRACE( 30, ( "__kmp_resume_template: T#%d exiting after signaling wake up for T#%d\n",
Jim Cownie5e8470a2013-09-27 10:38:44 +00001847 gtid, target_gtid ) );
1848}
1849
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001850void __kmp_resume_32(int target_gtid, kmp_flag_32 *flag) {
1851 __kmp_resume_template(target_gtid, flag);
1852}
1853void __kmp_resume_64(int target_gtid, kmp_flag_64 *flag) {
1854 __kmp_resume_template(target_gtid, flag);
1855}
1856void __kmp_resume_oncore(int target_gtid, kmp_flag_oncore *flag) {
1857 __kmp_resume_template(target_gtid, flag);
1858}
1859
Jim Cownie07ea89f2014-09-03 11:10:54 +00001860void
1861__kmp_resume_monitor()
1862{
Jonathan Peyton11dc82f2016-05-05 16:15:57 +00001863 KMP_TIME_DEVELOPER_BLOCK(USER_resume);
Jim Cownie07ea89f2014-09-03 11:10:54 +00001864 int status;
1865#ifdef KMP_DEBUG
1866 int gtid = TCR_4(__kmp_init_gtid) ? __kmp_get_gtid() : -1;
1867 KF_TRACE( 30, ( "__kmp_resume_monitor: T#%d wants to wakeup T#%d enter\n",
1868 gtid, KMP_GTID_MONITOR ) );
1869 KMP_DEBUG_ASSERT( gtid != KMP_GTID_MONITOR );
1870#endif
1871 status = pthread_mutex_lock( &__kmp_wait_mx.m_mutex );
1872 KMP_CHECK_SYSFAIL( "pthread_mutex_lock", status );
1873#ifdef DEBUG_SUSPEND
1874 {
1875 char buffer[128];
1876 __kmp_print_cond( buffer, &__kmp_wait_cv.c_cond );
1877 __kmp_printf( "__kmp_resume_monitor: T#%d resuming T#%d: %s\n", gtid, KMP_GTID_MONITOR, buffer );
1878 }
1879#endif
1880 status = pthread_cond_signal( &__kmp_wait_cv.c_cond );
1881 KMP_CHECK_SYSFAIL( "pthread_cond_signal", status );
1882 status = pthread_mutex_unlock( &__kmp_wait_mx.m_mutex );
1883 KMP_CHECK_SYSFAIL( "pthread_mutex_unlock", status );
1884 KF_TRACE( 30, ( "__kmp_resume_monitor: T#%d exiting after signaling wake up for T#%d\n",
1885 gtid, KMP_GTID_MONITOR ) );
1886}
Jim Cownie5e8470a2013-09-27 10:38:44 +00001887
1888/* ------------------------------------------------------------------------ */
1889/* ------------------------------------------------------------------------ */
1890
1891void
1892__kmp_yield( int cond )
1893{
1894 if (cond && __kmp_yielding_on) {
1895 sched_yield();
1896 }
1897}
1898
1899/* ------------------------------------------------------------------------ */
1900/* ------------------------------------------------------------------------ */
1901
1902void
1903__kmp_gtid_set_specific( int gtid )
1904{
Jonathan Peytonf2520102016-04-18 21:33:01 +00001905 if( __kmp_init_gtid ) {
1906 int status;
1907 status = pthread_setspecific( __kmp_gtid_threadprivate_key, (void*)(intptr_t)(gtid+1) );
1908 KMP_CHECK_SYSFAIL( "pthread_setspecific", status );
1909 } else {
1910 KA_TRACE( 50, ("__kmp_gtid_set_specific: runtime shutdown, returning\n" ) );
1911 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00001912}
1913
1914int
1915__kmp_gtid_get_specific()
1916{
1917 int gtid;
Jonathan Peytonf2520102016-04-18 21:33:01 +00001918 if ( !__kmp_init_gtid ) {
1919 KA_TRACE( 50, ("__kmp_gtid_get_specific: runtime shutdown, returning KMP_GTID_SHUTDOWN\n" ) );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001920 return KMP_GTID_SHUTDOWN;
1921 }
1922 gtid = (int)(size_t)pthread_getspecific( __kmp_gtid_threadprivate_key );
1923 if ( gtid == 0 ) {
1924 gtid = KMP_GTID_DNE;
1925 }
1926 else {
1927 gtid--;
1928 }
1929 KA_TRACE( 50, ("__kmp_gtid_get_specific: key:%d gtid:%d\n",
1930 __kmp_gtid_threadprivate_key, gtid ));
1931 return gtid;
1932}
1933
1934/* ------------------------------------------------------------------------ */
1935/* ------------------------------------------------------------------------ */
1936
1937double
1938__kmp_read_cpu_time( void )
1939{
1940 /*clock_t t;*/
1941 struct tms buffer;
1942
1943 /*t =*/ times( & buffer );
1944
1945 return (buffer.tms_utime + buffer.tms_cutime) / (double) CLOCKS_PER_SEC;
1946}
1947
1948int
1949__kmp_read_system_info( struct kmp_sys_info *info )
1950{
1951 int status;
1952 struct rusage r_usage;
1953
1954 memset( info, 0, sizeof( *info ) );
1955
1956 status = getrusage( RUSAGE_SELF, &r_usage);
1957 KMP_CHECK_SYSFAIL_ERRNO( "getrusage", status );
1958
1959 info->maxrss = r_usage.ru_maxrss; /* the maximum resident set size utilized (in kilobytes) */
1960 info->minflt = r_usage.ru_minflt; /* the number of page faults serviced without any I/O */
1961 info->majflt = r_usage.ru_majflt; /* the number of page faults serviced that required I/O */
1962 info->nswap = r_usage.ru_nswap; /* the number of times a process was "swapped" out of memory */
1963 info->inblock = r_usage.ru_inblock; /* the number of times the file system had to perform input */
1964 info->oublock = r_usage.ru_oublock; /* the number of times the file system had to perform output */
1965 info->nvcsw = r_usage.ru_nvcsw; /* the number of times a context switch was voluntarily */
1966 info->nivcsw = r_usage.ru_nivcsw; /* the number of times a context switch was forced */
1967
1968 return (status != 0);
1969}
1970
1971/* ------------------------------------------------------------------------ */
1972/* ------------------------------------------------------------------------ */
1973
Jim Cownie5e8470a2013-09-27 10:38:44 +00001974void
1975__kmp_read_system_time( double *delta )
1976{
1977 double t_ns;
1978 struct timeval tval;
1979 struct timespec stop;
1980 int status;
1981
1982 status = gettimeofday( &tval, NULL );
1983 KMP_CHECK_SYSFAIL_ERRNO( "gettimeofday", status );
1984 TIMEVAL_TO_TIMESPEC( &tval, &stop );
1985 t_ns = TS2NS(stop) - TS2NS(__kmp_sys_timer_data.start);
1986 *delta = (t_ns * 1e-9);
1987}
1988
1989void
1990__kmp_clear_system_time( void )
1991{
1992 struct timeval tval;
1993 int status;
1994 status = gettimeofday( &tval, NULL );
1995 KMP_CHECK_SYSFAIL_ERRNO( "gettimeofday", status );
1996 TIMEVAL_TO_TIMESPEC( &tval, &__kmp_sys_timer_data.start );
1997}
1998
1999/* ------------------------------------------------------------------------ */
2000/* ------------------------------------------------------------------------ */
2001
2002#ifdef BUILD_TV
2003
2004void
2005__kmp_tv_threadprivate_store( kmp_info_t *th, void *global_addr, void *thread_addr )
2006{
2007 struct tv_data *p;
2008
2009 p = (struct tv_data *) __kmp_allocate( sizeof( *p ) );
2010
2011 p->u.tp.global_addr = global_addr;
2012 p->u.tp.thread_addr = thread_addr;
2013
2014 p->type = (void *) 1;
2015
2016 p->next = th->th.th_local.tv_data;
2017 th->th.th_local.tv_data = p;
2018
2019 if ( p->next == 0 ) {
2020 int rc = pthread_setspecific( __kmp_tv_key, p );
2021 KMP_CHECK_SYSFAIL( "pthread_setspecific", rc );
2022 }
2023}
2024
2025#endif /* BUILD_TV */
2026
2027/* ------------------------------------------------------------------------ */
2028/* ------------------------------------------------------------------------ */
2029
2030static int
2031__kmp_get_xproc( void ) {
2032
2033 int r = 0;
2034
Joerg Sonnenberger7649cd42015-09-21 20:29:12 +00002035 #if KMP_OS_LINUX || KMP_OS_FREEBSD || KMP_OS_NETBSD
Jim Cownie5e8470a2013-09-27 10:38:44 +00002036
2037 r = sysconf( _SC_NPROCESSORS_ONLN );
2038
2039 #elif KMP_OS_DARWIN
2040
2041 // Bug C77011 High "OpenMP Threads and number of active cores".
2042
2043 // Find the number of available CPUs.
2044 kern_return_t rc;
2045 host_basic_info_data_t info;
2046 mach_msg_type_number_t num = HOST_BASIC_INFO_COUNT;
2047 rc = host_info( mach_host_self(), HOST_BASIC_INFO, (host_info_t) & info, & num );
2048 if ( rc == 0 && num == HOST_BASIC_INFO_COUNT ) {
2049 // Cannot use KA_TRACE() here because this code works before trace support is
2050 // initialized.
2051 r = info.avail_cpus;
2052 } else {
2053 KMP_WARNING( CantGetNumAvailCPU );
2054 KMP_INFORM( AssumedNumCPU );
2055 }; // if
2056
2057 #else
2058
2059 #error "Unknown or unsupported OS."
2060
2061 #endif
2062
2063 return r > 0 ? r : 2; /* guess value of 2 if OS told us 0 */
2064
2065} // __kmp_get_xproc
2066
Jim Cownie181b4bb2013-12-23 17:28:57 +00002067int
2068__kmp_read_from_file( char const *path, char const *format, ... )
2069{
2070 int result;
2071 va_list args;
Jim Cownie5e8470a2013-09-27 10:38:44 +00002072
Jim Cownie181b4bb2013-12-23 17:28:57 +00002073 va_start(args, format);
2074 FILE *f = fopen(path, "rb");
2075 if ( f == NULL )
2076 return 0;
2077 result = vfscanf(f, format, args);
2078 fclose(f);
Jim Cownie5e8470a2013-09-27 10:38:44 +00002079
Jim Cownie5e8470a2013-09-27 10:38:44 +00002080 return result;
Jim Cownie181b4bb2013-12-23 17:28:57 +00002081}
Jim Cownie5e8470a2013-09-27 10:38:44 +00002082
2083void
2084__kmp_runtime_initialize( void )
2085{
2086 int status;
2087 pthread_mutexattr_t mutex_attr;
2088 pthread_condattr_t cond_attr;
2089
2090 if ( __kmp_init_runtime ) {
2091 return;
2092 }; // if
2093
2094 #if ( KMP_ARCH_X86 || KMP_ARCH_X86_64 )
2095 if ( ! __kmp_cpuinfo.initialized ) {
2096 __kmp_query_cpuid( &__kmp_cpuinfo );
2097 }; // if
2098 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
2099
Jim Cownie5e8470a2013-09-27 10:38:44 +00002100 __kmp_xproc = __kmp_get_xproc();
2101
2102 if ( sysconf( _SC_THREADS ) ) {
2103
2104 /* Query the maximum number of threads */
2105 __kmp_sys_max_nth = sysconf( _SC_THREAD_THREADS_MAX );
2106 if ( __kmp_sys_max_nth == -1 ) {
2107 /* Unlimited threads for NPTL */
2108 __kmp_sys_max_nth = INT_MAX;
2109 }
2110 else if ( __kmp_sys_max_nth <= 1 ) {
2111 /* Can't tell, just use PTHREAD_THREADS_MAX */
2112 __kmp_sys_max_nth = KMP_MAX_NTH;
2113 }
2114
2115 /* Query the minimum stack size */
2116 __kmp_sys_min_stksize = sysconf( _SC_THREAD_STACK_MIN );
2117 if ( __kmp_sys_min_stksize <= 1 ) {
2118 __kmp_sys_min_stksize = KMP_MIN_STKSIZE;
2119 }
2120 }
2121
2122 /* Set up minimum number of threads to switch to TLS gtid */
2123 __kmp_tls_gtid_min = KMP_TLS_GTID_MIN;
2124
Jim Cownie5e8470a2013-09-27 10:38:44 +00002125 #ifdef BUILD_TV
2126 {
2127 int rc = pthread_key_create( & __kmp_tv_key, 0 );
2128 KMP_CHECK_SYSFAIL( "pthread_key_create", rc );
2129 }
2130 #endif
2131
2132 status = pthread_key_create( &__kmp_gtid_threadprivate_key, __kmp_internal_end_dest );
2133 KMP_CHECK_SYSFAIL( "pthread_key_create", status );
2134 status = pthread_mutexattr_init( & mutex_attr );
2135 KMP_CHECK_SYSFAIL( "pthread_mutexattr_init", status );
2136 status = pthread_mutex_init( & __kmp_wait_mx.m_mutex, & mutex_attr );
2137 KMP_CHECK_SYSFAIL( "pthread_mutex_init", status );
2138 status = pthread_condattr_init( & cond_attr );
2139 KMP_CHECK_SYSFAIL( "pthread_condattr_init", status );
2140 status = pthread_cond_init( & __kmp_wait_cv.c_cond, & cond_attr );
2141 KMP_CHECK_SYSFAIL( "pthread_cond_init", status );
2142#if USE_ITT_BUILD
2143 __kmp_itt_initialize();
2144#endif /* USE_ITT_BUILD */
2145
2146 __kmp_init_runtime = TRUE;
2147}
2148
2149void
2150__kmp_runtime_destroy( void )
2151{
2152 int status;
2153
2154 if ( ! __kmp_init_runtime ) {
2155 return; // Nothing to do.
2156 };
2157
2158#if USE_ITT_BUILD
2159 __kmp_itt_destroy();
2160#endif /* USE_ITT_BUILD */
2161
2162 status = pthread_key_delete( __kmp_gtid_threadprivate_key );
2163 KMP_CHECK_SYSFAIL( "pthread_key_delete", status );
2164 #ifdef BUILD_TV
2165 status = pthread_key_delete( __kmp_tv_key );
2166 KMP_CHECK_SYSFAIL( "pthread_key_delete", status );
2167 #endif
2168
2169 status = pthread_mutex_destroy( & __kmp_wait_mx.m_mutex );
2170 if ( status != 0 && status != EBUSY ) {
2171 KMP_SYSFAIL( "pthread_mutex_destroy", status );
2172 }
2173 status = pthread_cond_destroy( & __kmp_wait_cv.c_cond );
2174 if ( status != 0 && status != EBUSY ) {
2175 KMP_SYSFAIL( "pthread_cond_destroy", status );
2176 }
Alp Toker763b9392014-02-28 09:42:41 +00002177 #if KMP_AFFINITY_SUPPORTED
Jim Cownie5e8470a2013-09-27 10:38:44 +00002178 __kmp_affinity_uninitialize();
Jim Cownie5e8470a2013-09-27 10:38:44 +00002179 #endif
2180
2181 __kmp_init_runtime = FALSE;
2182}
2183
2184
2185/* Put the thread to sleep for a time period */
2186/* NOTE: not currently used anywhere */
2187void
2188__kmp_thread_sleep( int millis )
2189{
2190 sleep( ( millis + 500 ) / 1000 );
2191}
2192
2193/* Calculate the elapsed wall clock time for the user */
2194void
2195__kmp_elapsed( double *t )
2196{
2197 int status;
2198# ifdef FIX_SGI_CLOCK
2199 struct timespec ts;
2200
2201 status = clock_gettime( CLOCK_PROCESS_CPUTIME_ID, &ts );
2202 KMP_CHECK_SYSFAIL_ERRNO( "clock_gettime", status );
Jonathan Peyton1e7a1dd2015-06-04 17:29:13 +00002203 *t = (double) ts.tv_nsec * (1.0 / (double) KMP_NSEC_PER_SEC) +
Jim Cownie5e8470a2013-09-27 10:38:44 +00002204 (double) ts.tv_sec;
2205# else
2206 struct timeval tv;
2207
2208 status = gettimeofday( & tv, NULL );
2209 KMP_CHECK_SYSFAIL_ERRNO( "gettimeofday", status );
Jonathan Peyton1e7a1dd2015-06-04 17:29:13 +00002210 *t = (double) tv.tv_usec * (1.0 / (double) KMP_USEC_PER_SEC) +
Jim Cownie5e8470a2013-09-27 10:38:44 +00002211 (double) tv.tv_sec;
2212# endif
2213}
2214
2215/* Calculate the elapsed wall clock tick for the user */
2216void
2217__kmp_elapsed_tick( double *t )
2218{
2219 *t = 1 / (double) CLOCKS_PER_SEC;
2220}
2221
Jonathan Peyton377aa402016-04-14 16:00:37 +00002222/* Return the current time stamp in nsec */
2223kmp_uint64
2224__kmp_now_nsec()
2225{
2226 struct timeval t;
2227 gettimeofday(&t, NULL);
2228 return KMP_NSEC_PER_SEC*t.tv_sec + 1000*t.tv_usec;
2229}
2230
Jim Cownie5e8470a2013-09-27 10:38:44 +00002231/*
2232 Determine whether the given address is mapped into the current address space.
2233*/
2234
2235int
2236__kmp_is_address_mapped( void * addr ) {
2237
2238 int found = 0;
2239 int rc;
2240
Joerg Sonnenberger7649cd42015-09-21 20:29:12 +00002241 #if KMP_OS_LINUX || KMP_OS_FREEBSD
Jim Cownie5e8470a2013-09-27 10:38:44 +00002242
2243 /*
2244 On Linux* OS, read the /proc/<pid>/maps pseudo-file to get all the address ranges mapped
2245 into the address space.
2246 */
2247
2248 char * name = __kmp_str_format( "/proc/%d/maps", getpid() );
2249 FILE * file = NULL;
2250
2251 file = fopen( name, "r" );
2252 KMP_ASSERT( file != NULL );
2253
2254 for ( ; ; ) {
2255
2256 void * beginning = NULL;
2257 void * ending = NULL;
2258 char perms[ 5 ];
2259
2260 rc = fscanf( file, "%p-%p %4s %*[^\n]\n", & beginning, & ending, perms );
2261 if ( rc == EOF ) {
2262 break;
2263 }; // if
Andrey Churbanov74bf17b2015-04-02 13:27:08 +00002264 KMP_ASSERT( rc == 3 && KMP_STRLEN( perms ) == 4 ); // Make sure all fields are read.
Jim Cownie5e8470a2013-09-27 10:38:44 +00002265
2266 // Ending address is not included in the region, but beginning is.
2267 if ( ( addr >= beginning ) && ( addr < ending ) ) {
2268 perms[ 2 ] = 0; // 3th and 4th character does not matter.
2269 if ( strcmp( perms, "rw" ) == 0 ) {
2270 // Memory we are looking for should be readable and writable.
2271 found = 1;
2272 }; // if
2273 break;
2274 }; // if
2275
2276 }; // forever
2277
2278 // Free resources.
2279 fclose( file );
2280 KMP_INTERNAL_FREE( name );
2281
2282 #elif KMP_OS_DARWIN
2283
2284 /*
2285 On OS X*, /proc pseudo filesystem is not available. Try to read memory using vm
2286 interface.
2287 */
2288
2289 int buffer;
2290 vm_size_t count;
2291 rc =
2292 vm_read_overwrite(
2293 mach_task_self(), // Task to read memory of.
2294 (vm_address_t)( addr ), // Address to read from.
2295 1, // Number of bytes to be read.
2296 (vm_address_t)( & buffer ), // Address of buffer to save read bytes in.
2297 & count // Address of var to save number of read bytes in.
2298 );
2299 if ( rc == 0 ) {
2300 // Memory successfully read.
2301 found = 1;
2302 }; // if
2303
Joerg Sonnenberger1564f3c2015-09-21 20:02:45 +00002304 #elif KMP_OS_FREEBSD || KMP_OS_NETBSD
Alp Toker763b9392014-02-28 09:42:41 +00002305
Joerg Sonnenberger1564f3c2015-09-21 20:02:45 +00002306 // FIXME(FreeBSD, NetBSD): Implement this
Alp Toker763b9392014-02-28 09:42:41 +00002307 found = 1;
2308
Jim Cownie5e8470a2013-09-27 10:38:44 +00002309 #else
2310
2311 #error "Unknown or unsupported OS"
2312
2313 #endif
2314
2315 return found;
2316
2317} // __kmp_is_address_mapped
2318
2319#ifdef USE_LOAD_BALANCE
2320
2321
2322# if KMP_OS_DARWIN
2323
2324// The function returns the rounded value of the system load average
2325// during given time interval which depends on the value of
2326// __kmp_load_balance_interval variable (default is 60 sec, other values
2327// may be 300 sec or 900 sec).
2328// It returns -1 in case of error.
2329int
2330__kmp_get_load_balance( int max )
2331{
2332 double averages[3];
2333 int ret_avg = 0;
2334
2335 int res = getloadavg( averages, 3 );
2336
2337 //Check __kmp_load_balance_interval to determine which of averages to use.
2338 // getloadavg() may return the number of samples less than requested that is
2339 // less than 3.
2340 if ( __kmp_load_balance_interval < 180 && ( res >= 1 ) ) {
2341 ret_avg = averages[0];// 1 min
2342 } else if ( ( __kmp_load_balance_interval >= 180
2343 && __kmp_load_balance_interval < 600 ) && ( res >= 2 ) ) {
2344 ret_avg = averages[1];// 5 min
2345 } else if ( ( __kmp_load_balance_interval >= 600 ) && ( res == 3 ) ) {
2346 ret_avg = averages[2];// 15 min
Alp Toker8f2d3f02014-02-24 10:40:15 +00002347 } else {// Error occurred
Jim Cownie5e8470a2013-09-27 10:38:44 +00002348 return -1;
2349 }
2350
2351 return ret_avg;
2352}
2353
2354# else // Linux* OS
2355
2356// The fuction returns number of running (not sleeping) threads, or -1 in case of error.
2357// Error could be reported if Linux* OS kernel too old (without "/proc" support).
2358// Counting running threads stops if max running threads encountered.
2359int
2360__kmp_get_load_balance( int max )
2361{
2362 static int permanent_error = 0;
2363
2364 static int glb_running_threads = 0; /* Saved count of the running threads for the thread balance algortihm */
2365 static double glb_call_time = 0; /* Thread balance algorithm call time */
2366
2367 int running_threads = 0; // Number of running threads in the system.
2368
2369 DIR * proc_dir = NULL; // Handle of "/proc/" directory.
2370 struct dirent * proc_entry = NULL;
2371
2372 kmp_str_buf_t task_path; // "/proc/<pid>/task/<tid>/" path.
2373 DIR * task_dir = NULL; // Handle of "/proc/<pid>/task/<tid>/" directory.
2374 struct dirent * task_entry = NULL;
2375 int task_path_fixed_len;
2376
2377 kmp_str_buf_t stat_path; // "/proc/<pid>/task/<tid>/stat" path.
2378 int stat_file = -1;
2379 int stat_path_fixed_len;
2380
2381 int total_processes = 0; // Total number of processes in system.
2382 int total_threads = 0; // Total number of threads in system.
2383
2384 double call_time = 0.0;
2385
2386 __kmp_str_buf_init( & task_path );
2387 __kmp_str_buf_init( & stat_path );
2388
2389 __kmp_elapsed( & call_time );
2390
2391 if ( glb_call_time &&
2392 ( call_time - glb_call_time < __kmp_load_balance_interval ) ) {
2393 running_threads = glb_running_threads;
2394 goto finish;
2395 }
2396
2397 glb_call_time = call_time;
2398
2399 // Do not spend time on scanning "/proc/" if we have a permanent error.
2400 if ( permanent_error ) {
2401 running_threads = -1;
2402 goto finish;
2403 }; // if
2404
2405 if ( max <= 0 ) {
2406 max = INT_MAX;
2407 }; // if
2408
2409 // Open "/proc/" directory.
2410 proc_dir = opendir( "/proc" );
2411 if ( proc_dir == NULL ) {
2412 // Cannot open "/prroc/". Probably the kernel does not support it. Return an error now and
2413 // in subsequent calls.
2414 running_threads = -1;
2415 permanent_error = 1;
2416 goto finish;
2417 }; // if
2418
2419 // Initialize fixed part of task_path. This part will not change.
2420 __kmp_str_buf_cat( & task_path, "/proc/", 6 );
2421 task_path_fixed_len = task_path.used; // Remember number of used characters.
2422
2423 proc_entry = readdir( proc_dir );
2424 while ( proc_entry != NULL ) {
2425 // Proc entry is a directory and name starts with a digit. Assume it is a process'
2426 // directory.
2427 if ( proc_entry->d_type == DT_DIR && isdigit( proc_entry->d_name[ 0 ] ) ) {
2428
2429 ++ total_processes;
2430 // Make sure init process is the very first in "/proc", so we can replace
2431 // strcmp( proc_entry->d_name, "1" ) == 0 with simpler total_processes == 1.
2432 // We are going to check that total_processes == 1 => d_name == "1" is true (where
2433 // "=>" is implication). Since C++ does not have => operator, let us replace it with its
2434 // equivalent: a => b == ! a || b.
2435 KMP_DEBUG_ASSERT( total_processes != 1 || strcmp( proc_entry->d_name, "1" ) == 0 );
2436
2437 // Construct task_path.
2438 task_path.used = task_path_fixed_len; // Reset task_path to "/proc/".
Andrey Churbanov74bf17b2015-04-02 13:27:08 +00002439 __kmp_str_buf_cat( & task_path, proc_entry->d_name, KMP_STRLEN( proc_entry->d_name ) );
Jim Cownie5e8470a2013-09-27 10:38:44 +00002440 __kmp_str_buf_cat( & task_path, "/task", 5 );
2441
2442 task_dir = opendir( task_path.str );
2443 if ( task_dir == NULL ) {
2444 // Process can finish between reading "/proc/" directory entry and opening process'
2445 // "task/" directory. So, in general case we should not complain, but have to skip
2446 // this process and read the next one.
2447 // But on systems with no "task/" support we will spend lot of time to scan "/proc/"
2448 // tree again and again without any benefit. "init" process (its pid is 1) should
2449 // exist always, so, if we cannot open "/proc/1/task/" directory, it means "task/"
2450 // is not supported by kernel. Report an error now and in the future.
2451 if ( strcmp( proc_entry->d_name, "1" ) == 0 ) {
2452 running_threads = -1;
2453 permanent_error = 1;
2454 goto finish;
2455 }; // if
2456 } else {
2457 // Construct fixed part of stat file path.
2458 __kmp_str_buf_clear( & stat_path );
2459 __kmp_str_buf_cat( & stat_path, task_path.str, task_path.used );
2460 __kmp_str_buf_cat( & stat_path, "/", 1 );
2461 stat_path_fixed_len = stat_path.used;
2462
2463 task_entry = readdir( task_dir );
2464 while ( task_entry != NULL ) {
2465 // It is a directory and name starts with a digit.
2466 if ( proc_entry->d_type == DT_DIR && isdigit( task_entry->d_name[ 0 ] ) ) {
2467
2468 ++ total_threads;
2469
2470 // Consruct complete stat file path. Easiest way would be:
2471 // __kmp_str_buf_print( & stat_path, "%s/%s/stat", task_path.str, task_entry->d_name );
2472 // but seriae of __kmp_str_buf_cat works a bit faster.
2473 stat_path.used = stat_path_fixed_len; // Reset stat path to its fixed part.
Andrey Churbanov74bf17b2015-04-02 13:27:08 +00002474 __kmp_str_buf_cat( & stat_path, task_entry->d_name, KMP_STRLEN( task_entry->d_name ) );
Jim Cownie5e8470a2013-09-27 10:38:44 +00002475 __kmp_str_buf_cat( & stat_path, "/stat", 5 );
2476
2477 // Note: Low-level API (open/read/close) is used. High-level API
2478 // (fopen/fclose) works ~ 30 % slower.
2479 stat_file = open( stat_path.str, O_RDONLY );
2480 if ( stat_file == -1 ) {
2481 // We cannot report an error because task (thread) can terminate just
2482 // before reading this file.
2483 } else {
2484 /*
2485 Content of "stat" file looks like:
2486
2487 24285 (program) S ...
2488
2489 It is a single line (if program name does not include fanny
2490 symbols). First number is a thread id, then name of executable file
2491 name in paretheses, then state of the thread. We need just thread
2492 state.
2493
2494 Good news: Length of program name is 15 characters max. Longer
2495 names are truncated.
2496
2497 Thus, we need rather short buffer: 15 chars for program name +
2498 2 parenthesis, + 3 spaces + ~7 digits of pid = 37.
2499
2500 Bad news: Program name may contain special symbols like space,
2501 closing parenthesis, or even new line. This makes parsing "stat"
2502 file not 100 % reliable. In case of fanny program names parsing
2503 may fail (report incorrect thread state).
2504
2505 Parsing "status" file looks more promissing (due to different
2506 file structure and escaping special symbols) but reading and
2507 parsing of "status" file works slower.
2508
2509 -- ln
2510 */
2511 char buffer[ 65 ];
2512 int len;
2513 len = read( stat_file, buffer, sizeof( buffer ) - 1 );
2514 if ( len >= 0 ) {
2515 buffer[ len ] = 0;
2516 // Using scanf:
2517 // sscanf( buffer, "%*d (%*s) %c ", & state );
2518 // looks very nice, but searching for a closing parenthesis works a
2519 // bit faster.
2520 char * close_parent = strstr( buffer, ") " );
2521 if ( close_parent != NULL ) {
2522 char state = * ( close_parent + 2 );
2523 if ( state == 'R' ) {
2524 ++ running_threads;
2525 if ( running_threads >= max ) {
2526 goto finish;
2527 }; // if
2528 }; // if
2529 }; // if
2530 }; // if
2531 close( stat_file );
2532 stat_file = -1;
2533 }; // if
2534 }; // if
2535 task_entry = readdir( task_dir );
2536 }; // while
2537 closedir( task_dir );
2538 task_dir = NULL;
2539 }; // if
2540 }; // if
2541 proc_entry = readdir( proc_dir );
2542 }; // while
2543
2544 //
2545 // There _might_ be a timing hole where the thread executing this
2546 // code get skipped in the load balance, and running_threads is 0.
2547 // Assert in the debug builds only!!!
2548 //
2549 KMP_DEBUG_ASSERT( running_threads > 0 );
2550 if ( running_threads <= 0 ) {
2551 running_threads = 1;
2552 }
2553
2554 finish: // Clean up and exit.
2555 if ( proc_dir != NULL ) {
2556 closedir( proc_dir );
2557 }; // if
2558 __kmp_str_buf_free( & task_path );
2559 if ( task_dir != NULL ) {
2560 closedir( task_dir );
2561 }; // if
2562 __kmp_str_buf_free( & stat_path );
2563 if ( stat_file != -1 ) {
2564 close( stat_file );
2565 }; // if
2566
2567 glb_running_threads = running_threads;
2568
2569 return running_threads;
2570
2571} // __kmp_get_load_balance
2572
2573# endif // KMP_OS_DARWIN
2574
2575#endif // USE_LOAD_BALANCE
2576
Andrey Churbanovedc370e2015-08-05 11:23:10 +00002577#if !(KMP_ARCH_X86 || KMP_ARCH_X86_64 || KMP_MIC)
Jim Cownie3051f972014-08-07 10:12:54 +00002578
2579// we really only need the case with 1 argument, because CLANG always build
2580// a struct of pointers to shared variables referenced in the outlined function
2581int
2582__kmp_invoke_microtask( microtask_t pkfn,
2583 int gtid, int tid,
Jonathan Peyton122dd762015-07-13 18:55:45 +00002584 int argc, void *p_argv[]
2585#if OMPT_SUPPORT
2586 , void **exit_frame_ptr
2587#endif
2588)
2589{
2590#if OMPT_SUPPORT
2591 *exit_frame_ptr = __builtin_frame_address(0);
2592#endif
2593
Jim Cownie3051f972014-08-07 10:12:54 +00002594 switch (argc) {
2595 default:
2596 fprintf(stderr, "Too many args to microtask: %d!\n", argc);
2597 fflush(stderr);
2598 exit(-1);
2599 case 0:
2600 (*pkfn)(&gtid, &tid);
2601 break;
2602 case 1:
2603 (*pkfn)(&gtid, &tid, p_argv[0]);
2604 break;
2605 case 2:
2606 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1]);
2607 break;
2608 case 3:
2609 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2]);
2610 break;
2611 case 4:
2612 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3]);
2613 break;
2614 case 5:
2615 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4]);
2616 break;
2617 case 6:
2618 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2619 p_argv[5]);
2620 break;
2621 case 7:
2622 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2623 p_argv[5], p_argv[6]);
2624 break;
2625 case 8:
2626 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2627 p_argv[5], p_argv[6], p_argv[7]);
2628 break;
2629 case 9:
2630 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2631 p_argv[5], p_argv[6], p_argv[7], p_argv[8]);
2632 break;
2633 case 10:
2634 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2635 p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9]);
2636 break;
2637 case 11:
2638 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2639 p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9], p_argv[10]);
2640 break;
2641 case 12:
2642 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2643 p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9], p_argv[10],
2644 p_argv[11]);
2645 break;
2646 case 13:
2647 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2648 p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9], p_argv[10],
2649 p_argv[11], p_argv[12]);
2650 break;
2651 case 14:
2652 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2653 p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9], p_argv[10],
2654 p_argv[11], p_argv[12], p_argv[13]);
2655 break;
2656 case 15:
2657 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2658 p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9], p_argv[10],
2659 p_argv[11], p_argv[12], p_argv[13], p_argv[14]);
2660 break;
2661 }
2662
Jonathan Peyton122dd762015-07-13 18:55:45 +00002663#if OMPT_SUPPORT
2664 *exit_frame_ptr = 0;
2665#endif
2666
Jim Cownie3051f972014-08-07 10:12:54 +00002667 return 1;
2668}
2669
2670#endif
Jim Cownie181b4bb2013-12-23 17:28:57 +00002671
Jim Cownie5e8470a2013-09-27 10:38:44 +00002672// end of file //
2673