blob: 6c51301d1bfe650ab6b2d52c7bef11ba6e2b6a9c [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"
Paul Osmialowskifb043fd2016-05-16 09:44:11 +000021#include "kmp_lock.h"
Jim Cownie5e8470a2013-09-27 10:38:44 +000022#include "kmp_io.h"
Jim Cownie4cc4bb42014-10-07 16:25:50 +000023#include "kmp_stats.h"
24#include "kmp_wait_release.h"
Jim Cownie5e8470a2013-09-27 10:38:44 +000025
Joerg Sonnenberger1564f3c2015-09-21 20:02:45 +000026#if !KMP_OS_FREEBSD && !KMP_OS_NETBSD
Alp Toker763b9392014-02-28 09:42:41 +000027# include <alloca.h>
28#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +000029#include <unistd.h>
30#include <math.h> // HUGE_VAL.
31#include <sys/time.h>
32#include <sys/times.h>
33#include <sys/resource.h>
34#include <sys/syscall.h>
35
Jim Cownie3051f972014-08-07 10:12:54 +000036#if KMP_OS_LINUX && !KMP_OS_CNK
Jim Cownie5e8470a2013-09-27 10:38:44 +000037# include <sys/sysinfo.h>
Paul Osmialowskifb043fd2016-05-16 09:44:11 +000038# if KMP_USE_FUTEX
Jim Cownie5e8470a2013-09-27 10:38:44 +000039// We should really include <futex.h>, but that causes compatibility problems on different
40// Linux* OS distributions that either require that you include (or break when you try to include)
41// <pci/types.h>.
42// Since all we need is the two macros below (which are part of the kernel ABI, so can't change)
43// we just define the constants here and don't include <futex.h>
44# ifndef FUTEX_WAIT
45# define FUTEX_WAIT 0
46# endif
47# ifndef FUTEX_WAKE
48# define FUTEX_WAKE 1
49# endif
50# endif
51#elif KMP_OS_DARWIN
52# include <sys/sysctl.h>
53# include <mach/mach.h>
Alp Toker763b9392014-02-28 09:42:41 +000054#elif KMP_OS_FREEBSD
Alp Toker763b9392014-02-28 09:42:41 +000055# include <pthread_np.h>
Jim Cownie5e8470a2013-09-27 10:38:44 +000056#endif
57
Jim Cownie5e8470a2013-09-27 10:38:44 +000058#include <dirent.h>
59#include <ctype.h>
60#include <fcntl.h>
61
62/* ------------------------------------------------------------------------ */
63/* ------------------------------------------------------------------------ */
64
65struct kmp_sys_timer {
66 struct timespec start;
67};
68
69// Convert timespec to nanoseconds.
70#define TS2NS(timespec) (((timespec).tv_sec * 1e9) + (timespec).tv_nsec)
71
72static struct kmp_sys_timer __kmp_sys_timer_data;
73
74#if KMP_HANDLE_SIGNALS
75 typedef void (* sig_func_t )( int );
76 STATIC_EFI2_WORKAROUND struct sigaction __kmp_sighldrs[ NSIG ];
77 static sigset_t __kmp_sigset;
78#endif
79
80static int __kmp_init_runtime = FALSE;
81
82static int __kmp_fork_count = 0;
83
84static pthread_condattr_t __kmp_suspend_cond_attr;
85static pthread_mutexattr_t __kmp_suspend_mutex_attr;
86
87static kmp_cond_align_t __kmp_wait_cv;
88static kmp_mutex_align_t __kmp_wait_mx;
89
Jonathan Peytonb66d1aa2016-09-27 17:11:17 +000090double __kmp_ticks_per_nsec;
91
Jim Cownie5e8470a2013-09-27 10:38:44 +000092/* ------------------------------------------------------------------------ */
93/* ------------------------------------------------------------------------ */
94
95#ifdef DEBUG_SUSPEND
96static void
97__kmp_print_cond( char *buffer, kmp_cond_align_t *cond )
98{
Andrey Churbanov74bf17b2015-04-02 13:27:08 +000099 KMP_SNPRINTF( buffer, 128, "(cond (lock (%ld, %d)), (descr (%p)))",
Jim Cownie5e8470a2013-09-27 10:38:44 +0000100 cond->c_cond.__c_lock.__status, cond->c_cond.__c_lock.__spinlock,
101 cond->c_cond.__c_waiting );
102}
103#endif
104
105/* ------------------------------------------------------------------------ */
106/* ------------------------------------------------------------------------ */
107
Jim Cownie3051f972014-08-07 10:12:54 +0000108#if ( KMP_OS_LINUX && KMP_AFFINITY_SUPPORTED)
Jim Cownie5e8470a2013-09-27 10:38:44 +0000109
110/*
111 * Affinity support
112 */
113
114/*
115 * On some of the older OS's that we build on, these constants aren't present
116 * in <asm/unistd.h> #included from <sys.syscall.h>. They must be the same on
117 * all systems of the same arch where they are defined, and they cannot change.
118 * stone forever.
119 */
120
Jim Cownie181b4bb2013-12-23 17:28:57 +0000121# if KMP_ARCH_X86 || KMP_ARCH_ARM
Jim Cownie5e8470a2013-09-27 10:38:44 +0000122# ifndef __NR_sched_setaffinity
123# define __NR_sched_setaffinity 241
124# elif __NR_sched_setaffinity != 241
125# error Wrong code for setaffinity system call.
126# endif /* __NR_sched_setaffinity */
127# ifndef __NR_sched_getaffinity
128# define __NR_sched_getaffinity 242
129# elif __NR_sched_getaffinity != 242
130# error Wrong code for getaffinity system call.
131# endif /* __NR_sched_getaffinity */
132
Andrey Churbanovcbda8682015-01-13 14:43:35 +0000133# elif KMP_ARCH_AARCH64
134# ifndef __NR_sched_setaffinity
135# define __NR_sched_setaffinity 122
136# elif __NR_sched_setaffinity != 122
137# error Wrong code for setaffinity system call.
138# endif /* __NR_sched_setaffinity */
139# ifndef __NR_sched_getaffinity
140# define __NR_sched_getaffinity 123
141# elif __NR_sched_getaffinity != 123
142# error Wrong code for getaffinity system call.
143# endif /* __NR_sched_getaffinity */
144
Jim Cownie5e8470a2013-09-27 10:38:44 +0000145# elif KMP_ARCH_X86_64
146# ifndef __NR_sched_setaffinity
147# define __NR_sched_setaffinity 203
148# elif __NR_sched_setaffinity != 203
149# error Wrong code for setaffinity system call.
150# endif /* __NR_sched_setaffinity */
151# ifndef __NR_sched_getaffinity
152# define __NR_sched_getaffinity 204
153# elif __NR_sched_getaffinity != 204
154# error Wrong code for getaffinity system call.
155# endif /* __NR_sched_getaffinity */
156
Jim Cownie3051f972014-08-07 10:12:54 +0000157# elif KMP_ARCH_PPC64
158# ifndef __NR_sched_setaffinity
159# define __NR_sched_setaffinity 222
160# elif __NR_sched_setaffinity != 222
161# error Wrong code for setaffinity system call.
162# endif /* __NR_sched_setaffinity */
163# ifndef __NR_sched_getaffinity
164# define __NR_sched_getaffinity 223
165# elif __NR_sched_getaffinity != 223
166# error Wrong code for getaffinity system call.
167# endif /* __NR_sched_getaffinity */
168
169
Jim Cownie5e8470a2013-09-27 10:38:44 +0000170# else
171# error Unknown or unsupported architecture
172
173# endif /* KMP_ARCH_* */
174
175int
176__kmp_set_system_affinity( kmp_affin_mask_t const *mask, int abort_on_error )
177{
178 KMP_ASSERT2(KMP_AFFINITY_CAPABLE(),
179 "Illegal set affinity operation when not capable");
Jonathan Peyton01dcf362015-11-30 20:02:59 +0000180#if KMP_USE_HWLOC
181 int retval = hwloc_set_cpubind(__kmp_hwloc_topology, (hwloc_cpuset_t)mask, HWLOC_CPUBIND_THREAD);
182#else
Jim Cownie5e8470a2013-09-27 10:38:44 +0000183 int retval = syscall( __NR_sched_setaffinity, 0, __kmp_affin_mask_size, mask );
Jonathan Peyton01dcf362015-11-30 20:02:59 +0000184#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +0000185 if (retval >= 0) {
186 return 0;
187 }
188 int error = errno;
189 if (abort_on_error) {
190 __kmp_msg(
191 kmp_ms_fatal,
192 KMP_MSG( FatalSysError ),
193 KMP_ERR( error ),
194 __kmp_msg_null
195 );
196 }
197 return error;
198}
199
200int
201__kmp_get_system_affinity( kmp_affin_mask_t *mask, int abort_on_error )
202{
203 KMP_ASSERT2(KMP_AFFINITY_CAPABLE(),
204 "Illegal get affinity operation when not capable");
205
Jonathan Peyton01dcf362015-11-30 20:02:59 +0000206#if KMP_USE_HWLOC
207 int retval = hwloc_get_cpubind(__kmp_hwloc_topology, (hwloc_cpuset_t)mask, HWLOC_CPUBIND_THREAD);
208#else
Jim Cownie5e8470a2013-09-27 10:38:44 +0000209 int retval = syscall( __NR_sched_getaffinity, 0, __kmp_affin_mask_size, mask );
Jonathan Peyton01dcf362015-11-30 20:02:59 +0000210#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +0000211 if (retval >= 0) {
212 return 0;
213 }
214 int error = errno;
215 if (abort_on_error) {
216 __kmp_msg(
217 kmp_ms_fatal,
218 KMP_MSG( FatalSysError ),
219 KMP_ERR( error ),
220 __kmp_msg_null
221 );
222 }
223 return error;
224}
225
226void
227__kmp_affinity_bind_thread( int which )
228{
229 KMP_ASSERT2(KMP_AFFINITY_CAPABLE(),
230 "Illegal set affinity operation when not capable");
231
Jonathan Peyton01dcf362015-11-30 20:02:59 +0000232 kmp_affin_mask_t *mask;
233 KMP_CPU_ALLOC_ON_STACK(mask);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000234 KMP_CPU_ZERO(mask);
235 KMP_CPU_SET(which, mask);
236 __kmp_set_system_affinity(mask, TRUE);
Jonathan Peyton01dcf362015-11-30 20:02:59 +0000237 KMP_CPU_FREE_FROM_STACK(mask);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000238}
239
240/*
241 * Determine if we can access affinity functionality on this version of
242 * Linux* OS by checking __NR_sched_{get,set}affinity system calls, and set
243 * __kmp_affin_mask_size to the appropriate value (0 means not capable).
244 */
245void
246__kmp_affinity_determine_capable(const char *env_var)
247{
248 //
249 // Check and see if the OS supports thread affinity.
250 //
251
252# define KMP_CPU_SET_SIZE_LIMIT (1024*1024)
253
254 int gCode;
255 int sCode;
Jonathan Peyton9e696962016-09-02 20:35:47 +0000256 unsigned char *buf;
257 buf = ( unsigned char * ) KMP_INTERNAL_MALLOC( KMP_CPU_SET_SIZE_LIMIT );
Jim Cownie5e8470a2013-09-27 10:38:44 +0000258
259 // If Linux* OS:
260 // If the syscall fails or returns a suggestion for the size,
261 // then we don't have to search for an appropriate size.
262 gCode = syscall( __NR_sched_getaffinity, 0, KMP_CPU_SET_SIZE_LIMIT, buf );
263 KA_TRACE(30, ( "__kmp_affinity_determine_capable: "
Alp Toker8f2d3f02014-02-24 10:40:15 +0000264 "initial getaffinity call returned %d errno = %d\n",
Jim Cownie5e8470a2013-09-27 10:38:44 +0000265 gCode, errno));
266
267 //if ((gCode < 0) && (errno == ENOSYS))
268 if (gCode < 0) {
269 //
270 // System call not supported
271 //
272 if (__kmp_affinity_verbose || (__kmp_affinity_warnings
273 && (__kmp_affinity_type != affinity_none)
274 && (__kmp_affinity_type != affinity_default)
275 && (__kmp_affinity_type != affinity_disabled))) {
276 int error = errno;
277 __kmp_msg(
278 kmp_ms_warning,
279 KMP_MSG( GetAffSysCallNotSupported, env_var ),
280 KMP_ERR( error ),
281 __kmp_msg_null
282 );
283 }
Andrey Churbanov1f037e42015-03-10 09:15:26 +0000284 KMP_AFFINITY_DISABLE();
Jim Cownie5e8470a2013-09-27 10:38:44 +0000285 KMP_INTERNAL_FREE(buf);
286 return;
287 }
288 if (gCode > 0) { // Linux* OS only
289 // The optimal situation: the OS returns the size of the buffer
290 // it expects.
291 //
292 // A verification of correct behavior is that Isetaffinity on a NULL
293 // buffer with the same size fails with errno set to EFAULT.
294 sCode = syscall( __NR_sched_setaffinity, 0, gCode, NULL );
295 KA_TRACE(30, ( "__kmp_affinity_determine_capable: "
296 "setaffinity for mask size %d returned %d errno = %d\n",
297 gCode, sCode, errno));
298 if (sCode < 0) {
299 if (errno == ENOSYS) {
300 if (__kmp_affinity_verbose || (__kmp_affinity_warnings
301 && (__kmp_affinity_type != affinity_none)
302 && (__kmp_affinity_type != affinity_default)
303 && (__kmp_affinity_type != affinity_disabled))) {
304 int error = errno;
305 __kmp_msg(
306 kmp_ms_warning,
307 KMP_MSG( SetAffSysCallNotSupported, env_var ),
308 KMP_ERR( error ),
309 __kmp_msg_null
310 );
311 }
Andrey Churbanov1f037e42015-03-10 09:15:26 +0000312 KMP_AFFINITY_DISABLE();
Jim Cownie5e8470a2013-09-27 10:38:44 +0000313 KMP_INTERNAL_FREE(buf);
314 }
315 if (errno == EFAULT) {
Andrey Churbanov1f037e42015-03-10 09:15:26 +0000316 KMP_AFFINITY_ENABLE(gCode);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000317 KA_TRACE(10, ( "__kmp_affinity_determine_capable: "
318 "affinity supported (mask size %d)\n",
319 (int)__kmp_affin_mask_size));
320 KMP_INTERNAL_FREE(buf);
321 return;
322 }
323 }
324 }
325
326 //
327 // Call the getaffinity system call repeatedly with increasing set sizes
328 // until we succeed, or reach an upper bound on the search.
329 //
330 KA_TRACE(30, ( "__kmp_affinity_determine_capable: "
331 "searching for proper set size\n"));
332 int size;
333 for (size = 1; size <= KMP_CPU_SET_SIZE_LIMIT; size *= 2) {
334 gCode = syscall( __NR_sched_getaffinity, 0, size, buf );
335 KA_TRACE(30, ( "__kmp_affinity_determine_capable: "
336 "getaffinity for mask size %d returned %d errno = %d\n", size,
337 gCode, errno));
338
339 if (gCode < 0) {
340 if ( errno == ENOSYS )
341 {
342 //
343 // We shouldn't get here
344 //
345 KA_TRACE(30, ( "__kmp_affinity_determine_capable: "
346 "inconsistent OS call behavior: errno == ENOSYS for mask size %d\n",
347 size));
348 if (__kmp_affinity_verbose || (__kmp_affinity_warnings
349 && (__kmp_affinity_type != affinity_none)
350 && (__kmp_affinity_type != affinity_default)
351 && (__kmp_affinity_type != affinity_disabled))) {
352 int error = errno;
353 __kmp_msg(
354 kmp_ms_warning,
355 KMP_MSG( GetAffSysCallNotSupported, env_var ),
356 KMP_ERR( error ),
357 __kmp_msg_null
358 );
359 }
Andrey Churbanov1f037e42015-03-10 09:15:26 +0000360 KMP_AFFINITY_DISABLE();
Jim Cownie5e8470a2013-09-27 10:38:44 +0000361 KMP_INTERNAL_FREE(buf);
362 return;
363 }
364 continue;
365 }
366
367 sCode = syscall( __NR_sched_setaffinity, 0, gCode, NULL );
368 KA_TRACE(30, ( "__kmp_affinity_determine_capable: "
369 "setaffinity for mask size %d returned %d errno = %d\n",
370 gCode, sCode, errno));
371 if (sCode < 0) {
372 if (errno == ENOSYS) { // Linux* OS only
373 //
374 // We shouldn't get here
375 //
376 KA_TRACE(30, ( "__kmp_affinity_determine_capable: "
377 "inconsistent OS call behavior: errno == ENOSYS for mask size %d\n",
378 size));
379 if (__kmp_affinity_verbose || (__kmp_affinity_warnings
380 && (__kmp_affinity_type != affinity_none)
381 && (__kmp_affinity_type != affinity_default)
382 && (__kmp_affinity_type != affinity_disabled))) {
383 int error = errno;
384 __kmp_msg(
385 kmp_ms_warning,
386 KMP_MSG( SetAffSysCallNotSupported, env_var ),
387 KMP_ERR( error ),
388 __kmp_msg_null
389 );
390 }
Andrey Churbanov1f037e42015-03-10 09:15:26 +0000391 KMP_AFFINITY_DISABLE();
Jim Cownie5e8470a2013-09-27 10:38:44 +0000392 KMP_INTERNAL_FREE(buf);
393 return;
394 }
395 if (errno == EFAULT) {
Andrey Churbanov1f037e42015-03-10 09:15:26 +0000396 KMP_AFFINITY_ENABLE(gCode);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000397 KA_TRACE(10, ( "__kmp_affinity_determine_capable: "
398 "affinity supported (mask size %d)\n",
399 (int)__kmp_affin_mask_size));
400 KMP_INTERNAL_FREE(buf);
401 return;
402 }
403 }
404 }
405 //int error = errno; // save uncaught error code
406 KMP_INTERNAL_FREE(buf);
407 // errno = error; // restore uncaught error code, will be printed at the next KMP_WARNING below
408
409 //
410 // Affinity is not supported
411 //
Andrey Churbanov1f037e42015-03-10 09:15:26 +0000412 KMP_AFFINITY_DISABLE();
Jim Cownie5e8470a2013-09-27 10:38:44 +0000413 KA_TRACE(10, ( "__kmp_affinity_determine_capable: "
414 "cannot determine mask size - affinity not supported\n"));
415 if (__kmp_affinity_verbose || (__kmp_affinity_warnings
416 && (__kmp_affinity_type != affinity_none)
417 && (__kmp_affinity_type != affinity_default)
418 && (__kmp_affinity_type != affinity_disabled))) {
419 KMP_WARNING( AffCantGetMaskSize, env_var );
420 }
421}
422
Andrey Churbanovd39f11c2015-03-10 10:14:57 +0000423#endif // KMP_OS_LINUX && KMP_AFFINITY_SUPPORTED
Jim Cownie5e8470a2013-09-27 10:38:44 +0000424
Andrey Churbanovd39f11c2015-03-10 10:14:57 +0000425/* ------------------------------------------------------------------------ */
426/* ------------------------------------------------------------------------ */
427
Jonathan Peyton9d2412c2016-06-22 16:35:12 +0000428#if KMP_USE_FUTEX
Andrey Churbanovd39f11c2015-03-10 10:14:57 +0000429
430int
431__kmp_futex_determine_capable()
432{
433 int loc = 0;
434 int rc = syscall( __NR_futex, &loc, FUTEX_WAKE, 1, NULL, NULL, 0 );
435 int retval = ( rc == 0 ) || ( errno != ENOSYS );
436
437 KA_TRACE(10, ( "__kmp_futex_determine_capable: rc = %d errno = %d\n", rc,
438 errno ) );
439 KA_TRACE(10, ( "__kmp_futex_determine_capable: futex syscall%s supported\n",
440 retval ? "" : " not" ) );
441
442 return retval;
443}
444
Jonathan Peyton9d2412c2016-06-22 16:35:12 +0000445#endif // KMP_USE_FUTEX
Andrey Churbanovd39f11c2015-03-10 10:14:57 +0000446
447/* ------------------------------------------------------------------------ */
448/* ------------------------------------------------------------------------ */
449
450#if (KMP_ARCH_X86 || KMP_ARCH_X86_64) && (! KMP_ASM_INTRINS)
Jim Cownie5e8470a2013-09-27 10:38:44 +0000451/*
Andrey Churbanovd39f11c2015-03-10 10:14:57 +0000452 * Only 32-bit "add-exchange" instruction on IA-32 architecture causes us to
453 * use compare_and_store for these routines
Jim Cownie5e8470a2013-09-27 10:38:44 +0000454 */
455
Andrey Churbanov7b2ab712015-03-10 09:03:42 +0000456kmp_int8
457__kmp_test_then_or8( volatile kmp_int8 *p, kmp_int8 d )
458{
459 kmp_int8 old_value, new_value;
460
461 old_value = TCR_1( *p );
462 new_value = old_value | d;
463
464 while ( ! KMP_COMPARE_AND_STORE_REL8 ( p, old_value, new_value ) )
465 {
466 KMP_CPU_PAUSE();
467 old_value = TCR_1( *p );
468 new_value = old_value | d;
469 }
470 return old_value;
471}
472
473kmp_int8
474__kmp_test_then_and8( volatile kmp_int8 *p, kmp_int8 d )
475{
476 kmp_int8 old_value, new_value;
477
478 old_value = TCR_1( *p );
479 new_value = old_value & d;
480
481 while ( ! KMP_COMPARE_AND_STORE_REL8 ( p, old_value, new_value ) )
482 {
483 KMP_CPU_PAUSE();
484 old_value = TCR_1( *p );
485 new_value = old_value & d;
486 }
487 return old_value;
488}
489
Jim Cownie5e8470a2013-09-27 10:38:44 +0000490kmp_int32
491__kmp_test_then_or32( volatile kmp_int32 *p, kmp_int32 d )
492{
493 kmp_int32 old_value, new_value;
494
495 old_value = TCR_4( *p );
496 new_value = old_value | d;
497
Jim Cownie3051f972014-08-07 10:12:54 +0000498 while ( ! KMP_COMPARE_AND_STORE_REL32 ( p, old_value, new_value ) )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000499 {
500 KMP_CPU_PAUSE();
501 old_value = TCR_4( *p );
502 new_value = old_value | d;
503 }
504 return old_value;
505}
506
507kmp_int32
508__kmp_test_then_and32( volatile kmp_int32 *p, kmp_int32 d )
509{
510 kmp_int32 old_value, new_value;
511
512 old_value = TCR_4( *p );
513 new_value = old_value & d;
514
Jim Cownie3051f972014-08-07 10:12:54 +0000515 while ( ! KMP_COMPARE_AND_STORE_REL32 ( p, old_value, new_value ) )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000516 {
517 KMP_CPU_PAUSE();
518 old_value = TCR_4( *p );
519 new_value = old_value & d;
520 }
521 return old_value;
522}
523
Paul Osmialowski7e5e8682016-05-13 08:26:42 +0000524# if KMP_ARCH_X86 || KMP_ARCH_PPC64 || (KMP_OS_LINUX && KMP_ARCH_AARCH64)
Andrey Churbanovd39f11c2015-03-10 10:14:57 +0000525kmp_int8
526__kmp_test_then_add8( volatile kmp_int8 *p, kmp_int8 d )
527{
528 kmp_int8 old_value, new_value;
529
530 old_value = TCR_1( *p );
531 new_value = old_value + d;
532
533 while ( ! KMP_COMPARE_AND_STORE_REL8 ( p, old_value, new_value ) )
534 {
535 KMP_CPU_PAUSE();
536 old_value = TCR_1( *p );
537 new_value = old_value + d;
538 }
539 return old_value;
540}
541
Jim Cownie5e8470a2013-09-27 10:38:44 +0000542kmp_int64
543__kmp_test_then_add64( volatile kmp_int64 *p, kmp_int64 d )
544{
545 kmp_int64 old_value, new_value;
546
547 old_value = TCR_8( *p );
548 new_value = old_value + d;
549
Jim Cownie3051f972014-08-07 10:12:54 +0000550 while ( ! KMP_COMPARE_AND_STORE_REL64 ( p, old_value, new_value ) )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000551 {
552 KMP_CPU_PAUSE();
553 old_value = TCR_8( *p );
554 new_value = old_value + d;
555 }
556 return old_value;
557}
Paul Osmialowski7e5e8682016-05-13 08:26:42 +0000558# endif /* KMP_ARCH_X86 || KMP_ARCH_PPC64 || (KMP_OS_LINUX && KMP_ARCH_AARCH64) */
Jim Cownie5e8470a2013-09-27 10:38:44 +0000559
560kmp_int64
561__kmp_test_then_or64( volatile kmp_int64 *p, kmp_int64 d )
562{
563 kmp_int64 old_value, new_value;
564
565 old_value = TCR_8( *p );
566 new_value = old_value | d;
Jim Cownie3051f972014-08-07 10:12:54 +0000567 while ( ! KMP_COMPARE_AND_STORE_REL64 ( p, old_value, new_value ) )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000568 {
569 KMP_CPU_PAUSE();
570 old_value = TCR_8( *p );
571 new_value = old_value | d;
572 }
573 return old_value;
574}
575
576kmp_int64
577__kmp_test_then_and64( volatile kmp_int64 *p, kmp_int64 d )
578{
579 kmp_int64 old_value, new_value;
580
581 old_value = TCR_8( *p );
582 new_value = old_value & d;
Jim Cownie3051f972014-08-07 10:12:54 +0000583 while ( ! KMP_COMPARE_AND_STORE_REL64 ( p, old_value, new_value ) )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000584 {
585 KMP_CPU_PAUSE();
586 old_value = TCR_8( *p );
587 new_value = old_value & d;
588 }
589 return old_value;
590}
591
592#endif /* (KMP_ARCH_X86 || KMP_ARCH_X86_64) && (! KMP_ASM_INTRINS) */
593
594void
595__kmp_terminate_thread( int gtid )
596{
597 int status;
598 kmp_info_t *th = __kmp_threads[ gtid ];
599
600 if ( !th ) return;
601
602 #ifdef KMP_CANCEL_THREADS
603 KA_TRACE( 10, ("__kmp_terminate_thread: kill (%d)\n", gtid ) );
604 status = pthread_cancel( th->th.th_info.ds.ds_thread );
605 if ( status != 0 && status != ESRCH ) {
606 __kmp_msg(
607 kmp_ms_fatal,
608 KMP_MSG( CantTerminateWorkerThread ),
609 KMP_ERR( status ),
610 __kmp_msg_null
611 );
612 }; // if
613 #endif
614 __kmp_yield( TRUE );
615} //
616
617/* ------------------------------------------------------------------------ */
618/* ------------------------------------------------------------------------ */
619
620/* ------------------------------------------------------------------------ */
621/* ------------------------------------------------------------------------ */
622
623/*
624 * Set thread stack info according to values returned by
625 * pthread_getattr_np().
626 * If values are unreasonable, assume call failed and use
627 * incremental stack refinement method instead.
628 * Returns TRUE if the stack parameters could be determined exactly,
629 * FALSE if incremental refinement is necessary.
630 */
631static kmp_int32
632__kmp_set_stack_info( int gtid, kmp_info_t *th )
633{
634 int stack_data;
Joerg Sonnenberger1564f3c2015-09-21 20:02:45 +0000635#if KMP_OS_LINUX || KMP_OS_FREEBSD || KMP_OS_NETBSD
Jim Cownie5e8470a2013-09-27 10:38:44 +0000636 /* Linux* OS only -- no pthread_getattr_np support on OS X* */
637 pthread_attr_t attr;
638 int status;
639 size_t size = 0;
640 void * addr = 0;
641
642 /* Always do incremental stack refinement for ubermaster threads since the initial
643 thread stack range can be reduced by sibling thread creation so pthread_attr_getstack
644 may cause thread gtid aliasing */
645 if ( ! KMP_UBER_GTID(gtid) ) {
646
647 /* Fetch the real thread attributes */
648 status = pthread_attr_init( &attr );
649 KMP_CHECK_SYSFAIL( "pthread_attr_init", status );
Joerg Sonnenberger1564f3c2015-09-21 20:02:45 +0000650#if KMP_OS_FREEBSD || KMP_OS_NETBSD
Alp Toker763b9392014-02-28 09:42:41 +0000651 status = pthread_attr_get_np( pthread_self(), &attr );
652 KMP_CHECK_SYSFAIL( "pthread_attr_get_np", status );
653#else
Jim Cownie5e8470a2013-09-27 10:38:44 +0000654 status = pthread_getattr_np( pthread_self(), &attr );
655 KMP_CHECK_SYSFAIL( "pthread_getattr_np", status );
Alp Toker763b9392014-02-28 09:42:41 +0000656#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +0000657 status = pthread_attr_getstack( &attr, &addr, &size );
658 KMP_CHECK_SYSFAIL( "pthread_attr_getstack", status );
659 KA_TRACE( 60, ( "__kmp_set_stack_info: T#%d pthread_attr_getstack returned size: %lu, "
660 "low addr: %p\n",
661 gtid, size, addr ));
662
663 status = pthread_attr_destroy( &attr );
664 KMP_CHECK_SYSFAIL( "pthread_attr_destroy", status );
665 }
666
667 if ( size != 0 && addr != 0 ) { /* was stack parameter determination successful? */
668 /* Store the correct base and size */
669 TCW_PTR(th->th.th_info.ds.ds_stackbase, (((char *)addr) + size));
670 TCW_PTR(th->th.th_info.ds.ds_stacksize, size);
671 TCW_4(th->th.th_info.ds.ds_stackgrow, FALSE);
672 return TRUE;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000673 }
Joerg Sonnenberger1564f3c2015-09-21 20:02:45 +0000674#endif /* KMP_OS_LINUX || KMP_OS_FREEBSD || KMP_OS_NETBSD */
Alp Toker763b9392014-02-28 09:42:41 +0000675 /* Use incremental refinement starting from initial conservative estimate */
676 TCW_PTR(th->th.th_info.ds.ds_stacksize, 0);
677 TCW_PTR(th -> th.th_info.ds.ds_stackbase, &stack_data);
678 TCW_4(th->th.th_info.ds.ds_stackgrow, TRUE);
679 return FALSE;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000680}
681
682static void*
683__kmp_launch_worker( void *thr )
684{
685 int status, old_type, old_state;
686#ifdef KMP_BLOCK_SIGNALS
687 sigset_t new_set, old_set;
688#endif /* KMP_BLOCK_SIGNALS */
689 void *exit_val;
Joerg Sonnenberger1564f3c2015-09-21 20:02:45 +0000690#if KMP_OS_LINUX || KMP_OS_FREEBSD || KMP_OS_NETBSD
Andrey Churbanov368b70e2015-08-05 11:12:45 +0000691 void * volatile padding = 0;
Jonathan Peyton2321d572015-06-08 19:25:25 +0000692#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +0000693 int gtid;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000694
695 gtid = ((kmp_info_t*)thr) -> th.th_info.ds.ds_gtid;
696 __kmp_gtid_set_specific( gtid );
697#ifdef KMP_TDATA_GTID
698 __kmp_gtid = gtid;
699#endif
Jim Cownie4cc4bb42014-10-07 16:25:50 +0000700#if KMP_STATS_ENABLED
701 // set __thread local index to point to thread-specific stats
702 __kmp_stats_thread_ptr = ((kmp_info_t*)thr)->th.th_stats;
Jonathan Peyton11dc82f2016-05-05 16:15:57 +0000703 KMP_START_EXPLICIT_TIMER(OMP_worker_thread_life);
704 KMP_SET_THREAD_STATE(IDLE);
705 KMP_INIT_PARTITIONED_TIMERS(OMP_idle);
Jim Cownie4cc4bb42014-10-07 16:25:50 +0000706#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +0000707
708#if USE_ITT_BUILD
709 __kmp_itt_thread_name( gtid );
710#endif /* USE_ITT_BUILD */
711
Alp Toker763b9392014-02-28 09:42:41 +0000712#if KMP_AFFINITY_SUPPORTED
Jim Cownie5e8470a2013-09-27 10:38:44 +0000713 __kmp_affinity_set_init_mask( gtid, FALSE );
Jim Cownie5e8470a2013-09-27 10:38:44 +0000714#endif
715
716#ifdef KMP_CANCEL_THREADS
717 status = pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, & old_type );
718 KMP_CHECK_SYSFAIL( "pthread_setcanceltype", status );
719 /* josh todo: isn't PTHREAD_CANCEL_ENABLE default for newly-created threads? */
720 status = pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, & old_state );
721 KMP_CHECK_SYSFAIL( "pthread_setcancelstate", status );
722#endif
723
724#if KMP_ARCH_X86 || KMP_ARCH_X86_64
725 //
726 // Set the FP control regs to be a copy of
727 // the parallel initialization thread's.
728 //
729 __kmp_clear_x87_fpu_status_word();
730 __kmp_load_x87_fpu_control_word( &__kmp_init_x87_fpu_control_word );
731 __kmp_load_mxcsr( &__kmp_init_mxcsr );
732#endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
733
734#ifdef KMP_BLOCK_SIGNALS
735 status = sigfillset( & new_set );
736 KMP_CHECK_SYSFAIL_ERRNO( "sigfillset", status );
737 status = pthread_sigmask( SIG_BLOCK, & new_set, & old_set );
738 KMP_CHECK_SYSFAIL( "pthread_sigmask", status );
739#endif /* KMP_BLOCK_SIGNALS */
740
Joerg Sonnenberger1564f3c2015-09-21 20:02:45 +0000741#if KMP_OS_LINUX || KMP_OS_FREEBSD || KMP_OS_NETBSD
Jim Cownie5e8470a2013-09-27 10:38:44 +0000742 if ( __kmp_stkoffset > 0 && gtid > 0 ) {
Andrey Churbanov74bf17b2015-04-02 13:27:08 +0000743 padding = KMP_ALLOCA( gtid * __kmp_stkoffset );
Jim Cownie5e8470a2013-09-27 10:38:44 +0000744 }
745#endif
746
747 KMP_MB();
748 __kmp_set_stack_info( gtid, (kmp_info_t*)thr );
749
750 __kmp_check_stack_overlap( (kmp_info_t*)thr );
751
752 exit_val = __kmp_launch_thread( (kmp_info_t *) thr );
753
754#ifdef KMP_BLOCK_SIGNALS
755 status = pthread_sigmask( SIG_SETMASK, & old_set, NULL );
756 KMP_CHECK_SYSFAIL( "pthread_sigmask", status );
757#endif /* KMP_BLOCK_SIGNALS */
758
759 return exit_val;
760}
761
Jonathan Peytonb66d1aa2016-09-27 17:11:17 +0000762#if KMP_USE_MONITOR
Jim Cownie5e8470a2013-09-27 10:38:44 +0000763/* The monitor thread controls all of the threads in the complex */
764
765static void*
766__kmp_launch_monitor( void *thr )
767{
768 int status, old_type, old_state;
769#ifdef KMP_BLOCK_SIGNALS
770 sigset_t new_set;
771#endif /* KMP_BLOCK_SIGNALS */
772 struct timespec interval;
773 int yield_count;
774 int yield_cycles = 0;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000775
776 KMP_MB(); /* Flush all pending memory write invalidates. */
777
778 KA_TRACE( 10, ("__kmp_launch_monitor: #1 launched\n" ) );
779
780 /* register us as the monitor thread */
781 __kmp_gtid_set_specific( KMP_GTID_MONITOR );
782#ifdef KMP_TDATA_GTID
783 __kmp_gtid = KMP_GTID_MONITOR;
784#endif
785
786 KMP_MB();
787
788#if USE_ITT_BUILD
789 __kmp_itt_thread_ignore(); // Instruct Intel(R) Threading Tools to ignore monitor thread.
790#endif /* USE_ITT_BUILD */
791
792 __kmp_set_stack_info( ((kmp_info_t*)thr)->th.th_info.ds.ds_gtid, (kmp_info_t*)thr );
793
794 __kmp_check_stack_overlap( (kmp_info_t*)thr );
795
796#ifdef KMP_CANCEL_THREADS
797 status = pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, & old_type );
798 KMP_CHECK_SYSFAIL( "pthread_setcanceltype", status );
799 /* josh todo: isn't PTHREAD_CANCEL_ENABLE default for newly-created threads? */
800 status = pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, & old_state );
801 KMP_CHECK_SYSFAIL( "pthread_setcancelstate", status );
802#endif
803
804 #if KMP_REAL_TIME_FIX
805 // This is a potential fix which allows application with real-time scheduling policy work.
806 // However, decision about the fix is not made yet, so it is disabled by default.
807 { // Are program started with real-time scheduling policy?
808 int sched = sched_getscheduler( 0 );
809 if ( sched == SCHED_FIFO || sched == SCHED_RR ) {
810 // Yes, we are a part of real-time application. Try to increase the priority of the
811 // monitor.
812 struct sched_param param;
813 int max_priority = sched_get_priority_max( sched );
814 int rc;
815 KMP_WARNING( RealTimeSchedNotSupported );
816 sched_getparam( 0, & param );
817 if ( param.sched_priority < max_priority ) {
818 param.sched_priority += 1;
819 rc = sched_setscheduler( 0, sched, & param );
820 if ( rc != 0 ) {
821 int error = errno;
822 __kmp_msg(
823 kmp_ms_warning,
824 KMP_MSG( CantChangeMonitorPriority ),
825 KMP_ERR( error ),
826 KMP_MSG( MonitorWillStarve ),
827 __kmp_msg_null
828 );
829 }; // if
830 } else {
831 // We cannot abort here, because number of CPUs may be enough for all the threads,
832 // including the monitor thread, so application could potentially work...
833 __kmp_msg(
834 kmp_ms_warning,
835 KMP_MSG( RunningAtMaxPriority ),
836 KMP_MSG( MonitorWillStarve ),
837 KMP_HNT( RunningAtMaxPriority ),
838 __kmp_msg_null
839 );
840 }; // if
841 }; // if
Jim Cownie4cc4bb42014-10-07 16:25:50 +0000842 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 +0000843 }
844 #endif // KMP_REAL_TIME_FIX
845
846 KMP_MB(); /* Flush all pending memory write invalidates. */
847
848 if ( __kmp_monitor_wakeups == 1 ) {
849 interval.tv_sec = 1;
850 interval.tv_nsec = 0;
851 } else {
852 interval.tv_sec = 0;
Jonathan Peyton1e7a1dd2015-06-04 17:29:13 +0000853 interval.tv_nsec = (KMP_NSEC_PER_SEC / __kmp_monitor_wakeups);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000854 }
855
856 KA_TRACE( 10, ("__kmp_launch_monitor: #2 monitor\n" ) );
857
858 if (__kmp_yield_cycle) {
859 __kmp_yielding_on = 0; /* Start out with yielding shut off */
860 yield_count = __kmp_yield_off_count;
861 } else {
862 __kmp_yielding_on = 1; /* Yielding is on permanently */
863 }
864
865 while( ! TCR_4( __kmp_global.g.g_done ) ) {
866 struct timespec now;
867 struct timeval tval;
868
869 /* This thread monitors the state of the system */
870
871 KA_TRACE( 15, ( "__kmp_launch_monitor: update\n" ) );
872
873 status = gettimeofday( &tval, NULL );
874 KMP_CHECK_SYSFAIL_ERRNO( "gettimeofday", status );
875 TIMEVAL_TO_TIMESPEC( &tval, &now );
876
877 now.tv_sec += interval.tv_sec;
878 now.tv_nsec += interval.tv_nsec;
879
Jonathan Peyton1e7a1dd2015-06-04 17:29:13 +0000880 if (now.tv_nsec >= KMP_NSEC_PER_SEC) {
Jim Cownie5e8470a2013-09-27 10:38:44 +0000881 now.tv_sec += 1;
Jonathan Peyton1e7a1dd2015-06-04 17:29:13 +0000882 now.tv_nsec -= KMP_NSEC_PER_SEC;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000883 }
884
885 status = pthread_mutex_lock( & __kmp_wait_mx.m_mutex );
886 KMP_CHECK_SYSFAIL( "pthread_mutex_lock", status );
Jim Cownie07ea89f2014-09-03 11:10:54 +0000887 // AC: the monitor should not fall asleep if g_done has been set
888 if ( !TCR_4(__kmp_global.g.g_done) ) { // check once more under mutex
889 status = pthread_cond_timedwait( &__kmp_wait_cv.c_cond, &__kmp_wait_mx.m_mutex, &now );
890 if ( status != 0 ) {
891 if ( status != ETIMEDOUT && status != EINTR ) {
892 KMP_SYSFAIL( "pthread_cond_timedwait", status );
893 };
Jim Cownie5e8470a2013-09-27 10:38:44 +0000894 };
895 };
Jim Cownie5e8470a2013-09-27 10:38:44 +0000896 status = pthread_mutex_unlock( & __kmp_wait_mx.m_mutex );
897 KMP_CHECK_SYSFAIL( "pthread_mutex_unlock", status );
898
899 if (__kmp_yield_cycle) {
900 yield_cycles++;
901 if ( (yield_cycles % yield_count) == 0 ) {
902 if (__kmp_yielding_on) {
903 __kmp_yielding_on = 0; /* Turn it off now */
904 yield_count = __kmp_yield_off_count;
905 } else {
906 __kmp_yielding_on = 1; /* Turn it on now */
907 yield_count = __kmp_yield_on_count;
908 }
909 yield_cycles = 0;
910 }
911 } else {
912 __kmp_yielding_on = 1;
913 }
914
915 TCW_4( __kmp_global.g.g_time.dt.t_value,
916 TCR_4( __kmp_global.g.g_time.dt.t_value ) + 1 );
917
918 KMP_MB(); /* Flush all pending memory write invalidates. */
919 }
920
921 KA_TRACE( 10, ("__kmp_launch_monitor: #3 cleanup\n" ) );
922
923#ifdef KMP_BLOCK_SIGNALS
924 status = sigfillset( & new_set );
925 KMP_CHECK_SYSFAIL_ERRNO( "sigfillset", status );
926 status = pthread_sigmask( SIG_UNBLOCK, & new_set, NULL );
927 KMP_CHECK_SYSFAIL( "pthread_sigmask", status );
928#endif /* KMP_BLOCK_SIGNALS */
929
930 KA_TRACE( 10, ("__kmp_launch_monitor: #4 finished\n" ) );
931
932 if( __kmp_global.g.g_abort != 0 ) {
933 /* now we need to terminate the worker threads */
934 /* the value of t_abort is the signal we caught */
935
936 int gtid;
937
938 KA_TRACE( 10, ("__kmp_launch_monitor: #5 terminate sig=%d\n", __kmp_global.g.g_abort ) );
939
940 /* terminate the OpenMP worker threads */
941 /* TODO this is not valid for sibling threads!!
942 * the uber master might not be 0 anymore.. */
943 for (gtid = 1; gtid < __kmp_threads_capacity; ++gtid)
944 __kmp_terminate_thread( gtid );
945
946 __kmp_cleanup();
947
948 KA_TRACE( 10, ("__kmp_launch_monitor: #6 raise sig=%d\n", __kmp_global.g.g_abort ) );
949
950 if (__kmp_global.g.g_abort > 0)
951 raise( __kmp_global.g.g_abort );
952
953 }
954
955 KA_TRACE( 10, ("__kmp_launch_monitor: #7 exit\n" ) );
956
957 return thr;
958}
Jonathan Peytonb66d1aa2016-09-27 17:11:17 +0000959#endif // KMP_USE_MONITOR
Jim Cownie5e8470a2013-09-27 10:38:44 +0000960
961void
962__kmp_create_worker( int gtid, kmp_info_t *th, size_t stack_size )
963{
964 pthread_t handle;
965 pthread_attr_t thread_attr;
966 int status;
967
968
969 th->th.th_info.ds.ds_gtid = gtid;
970
Jim Cownie4cc4bb42014-10-07 16:25:50 +0000971#if KMP_STATS_ENABLED
972 // sets up worker thread stats
973 __kmp_acquire_tas_lock(&__kmp_stats_lock, gtid);
974
975 // th->th.th_stats is used to transfer thread specific stats-pointer to __kmp_launch_worker
976 // So when thread is created (goes into __kmp_launch_worker) it will
977 // set it's __thread local pointer to th->th.th_stats
978 th->th.th_stats = __kmp_stats_list.push_back(gtid);
979 if(KMP_UBER_GTID(gtid)) {
980 __kmp_stats_start_time = tsc_tick_count::now();
981 __kmp_stats_thread_ptr = th->th.th_stats;
982 __kmp_stats_init();
Jonathan Peyton11dc82f2016-05-05 16:15:57 +0000983 KMP_START_EXPLICIT_TIMER(OMP_worker_thread_life);
984 KMP_SET_THREAD_STATE(SERIAL_REGION);
985 KMP_INIT_PARTITIONED_TIMERS(OMP_serial);
Jim Cownie4cc4bb42014-10-07 16:25:50 +0000986 }
987 __kmp_release_tas_lock(&__kmp_stats_lock, gtid);
988
989#endif // KMP_STATS_ENABLED
990
Jim Cownie5e8470a2013-09-27 10:38:44 +0000991 if ( KMP_UBER_GTID(gtid) ) {
992 KA_TRACE( 10, ("__kmp_create_worker: uber thread (%d)\n", gtid ) );
993 th -> th.th_info.ds.ds_thread = pthread_self();
994 __kmp_set_stack_info( gtid, th );
995 __kmp_check_stack_overlap( th );
996 return;
997 }; // if
998
999 KA_TRACE( 10, ("__kmp_create_worker: try to create thread (%d)\n", gtid ) );
1000
1001 KMP_MB(); /* Flush all pending memory write invalidates. */
1002
1003#ifdef KMP_THREAD_ATTR
Jonathan Peyton749b4d52016-01-27 21:02:04 +00001004 status = pthread_attr_init( &thread_attr );
1005 if ( status != 0 ) {
1006 __kmp_msg(kmp_ms_fatal, KMP_MSG( CantInitThreadAttrs ), KMP_ERR( status ), __kmp_msg_null);
1007 }; // if
1008 status = pthread_attr_setdetachstate( & thread_attr, PTHREAD_CREATE_JOINABLE );
1009 if ( status != 0 ) {
1010 __kmp_msg(kmp_ms_fatal, KMP_MSG( CantSetWorkerState ), KMP_ERR( status ), __kmp_msg_null);
1011 }; // if
Jim Cownie5e8470a2013-09-27 10:38:44 +00001012
Jonathan Peyton61118492016-05-20 19:03:38 +00001013 /* Set stack size for this thread now.
Jonathan Peyton749b4d52016-01-27 21:02:04 +00001014 * The multiple of 2 is there because on some machines, requesting an unusual stacksize
1015 * causes the thread to have an offset before the dummy alloca() takes place to create the
Jonathan Peyton61118492016-05-20 19:03:38 +00001016 * offset. Since we want the user to have a sufficient stacksize AND support a stack offset, we
Jonathan Peyton749b4d52016-01-27 21:02:04 +00001017 * alloca() twice the offset so that the upcoming alloca() does not eliminate any premade
1018 * offset, and also gives the user the stack space they requested for all threads */
1019 stack_size += gtid * __kmp_stkoffset * 2;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001020
Jonathan Peyton749b4d52016-01-27 21:02:04 +00001021 KA_TRACE( 10, ( "__kmp_create_worker: T#%d, default stacksize = %lu bytes, "
1022 "__kmp_stksize = %lu bytes, final stacksize = %lu bytes\n",
1023 gtid, KMP_DEFAULT_STKSIZE, __kmp_stksize, stack_size ) );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001024
1025# ifdef _POSIX_THREAD_ATTR_STACKSIZE
Jonathan Peyton749b4d52016-01-27 21:02:04 +00001026 status = pthread_attr_setstacksize( & thread_attr, stack_size );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001027# ifdef KMP_BACKUP_STKSIZE
Jonathan Peyton749b4d52016-01-27 21:02:04 +00001028 if ( status != 0 ) {
1029 if ( ! __kmp_env_stksize ) {
1030 stack_size = KMP_BACKUP_STKSIZE + gtid * __kmp_stkoffset;
1031 __kmp_stksize = KMP_BACKUP_STKSIZE;
1032 KA_TRACE( 10, ("__kmp_create_worker: T#%d, default stacksize = %lu bytes, "
1033 "__kmp_stksize = %lu bytes, (backup) final stacksize = %lu "
1034 "bytes\n",
1035 gtid, KMP_DEFAULT_STKSIZE, __kmp_stksize, stack_size )
1036 );
1037 status = pthread_attr_setstacksize( &thread_attr, stack_size );
1038 }; // if
1039 }; // if
Jim Cownie5e8470a2013-09-27 10:38:44 +00001040# endif /* KMP_BACKUP_STKSIZE */
Jonathan Peyton749b4d52016-01-27 21:02:04 +00001041 if ( status != 0 ) {
1042 __kmp_msg(kmp_ms_fatal, KMP_MSG( CantSetWorkerStackSize, stack_size ), KMP_ERR( status ),
1043 KMP_HNT( ChangeWorkerStackSize ), __kmp_msg_null);
1044 }; // if
Jim Cownie5e8470a2013-09-27 10:38:44 +00001045# endif /* _POSIX_THREAD_ATTR_STACKSIZE */
Jonathan Peyton749b4d52016-01-27 21:02:04 +00001046
Jim Cownie5e8470a2013-09-27 10:38:44 +00001047#endif /* KMP_THREAD_ATTR */
1048
Jonathan Peyton749b4d52016-01-27 21:02:04 +00001049 status = pthread_create( & handle, & thread_attr, __kmp_launch_worker, (void *) th );
1050 if ( status != 0 || ! handle ) { // ??? Why do we check handle??
Jim Cownie5e8470a2013-09-27 10:38:44 +00001051#ifdef _POSIX_THREAD_ATTR_STACKSIZE
Jonathan Peyton749b4d52016-01-27 21:02:04 +00001052 if ( status == EINVAL ) {
1053 __kmp_msg(kmp_ms_fatal, KMP_MSG( CantSetWorkerStackSize, stack_size ), KMP_ERR( status ),
1054 KMP_HNT( IncreaseWorkerStackSize ), __kmp_msg_null);
1055 };
1056 if ( status == ENOMEM ) {
1057 __kmp_msg(kmp_ms_fatal, KMP_MSG( CantSetWorkerStackSize, stack_size ), KMP_ERR( status ),
1058 KMP_HNT( DecreaseWorkerStackSize ), __kmp_msg_null);
1059 };
Jim Cownie5e8470a2013-09-27 10:38:44 +00001060#endif /* _POSIX_THREAD_ATTR_STACKSIZE */
Jonathan Peyton749b4d52016-01-27 21:02:04 +00001061 if ( status == EAGAIN ) {
1062 __kmp_msg(kmp_ms_fatal, KMP_MSG( NoResourcesForWorkerThread ), KMP_ERR( status ),
1063 KMP_HNT( Decrease_NUM_THREADS ), __kmp_msg_null);
1064 }; // if
1065 KMP_SYSFAIL( "pthread_create", status );
1066 }; // if
Jim Cownie5e8470a2013-09-27 10:38:44 +00001067
Jonathan Peyton749b4d52016-01-27 21:02:04 +00001068 th->th.th_info.ds.ds_thread = handle;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001069
1070#ifdef KMP_THREAD_ATTR
Jonathan Peyton749b4d52016-01-27 21:02:04 +00001071 status = pthread_attr_destroy( & thread_attr );
1072 if ( status ) {
1073 __kmp_msg(kmp_ms_warning, KMP_MSG( CantDestroyThreadAttrs ), KMP_ERR( status ), __kmp_msg_null);
1074 }; // if
Jim Cownie5e8470a2013-09-27 10:38:44 +00001075#endif /* KMP_THREAD_ATTR */
1076
1077 KMP_MB(); /* Flush all pending memory write invalidates. */
1078
1079 KA_TRACE( 10, ("__kmp_create_worker: done creating thread (%d)\n", gtid ) );
1080
1081} // __kmp_create_worker
1082
1083
Jonathan Peytonb66d1aa2016-09-27 17:11:17 +00001084#if KMP_USE_MONITOR
Jim Cownie5e8470a2013-09-27 10:38:44 +00001085void
1086__kmp_create_monitor( kmp_info_t *th )
1087{
1088 pthread_t handle;
1089 pthread_attr_t thread_attr;
1090 size_t size;
1091 int status;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001092 int auto_adj_size = FALSE;
1093
Jonathan Peyton4fee5f62015-12-18 23:20:36 +00001094 if( __kmp_dflt_blocktime == KMP_MAX_BLOCKTIME ) {
1095 // We don't need monitor thread in case of MAX_BLOCKTIME
1096 KA_TRACE( 10, ("__kmp_create_monitor: skipping monitor thread because of MAX blocktime\n" ) );
1097 th->th.th_info.ds.ds_tid = 0; // this makes reap_monitor no-op
1098 th->th.th_info.ds.ds_gtid = 0;
1099 return;
1100 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00001101 KA_TRACE( 10, ("__kmp_create_monitor: try to create monitor\n" ) );
1102
1103 KMP_MB(); /* Flush all pending memory write invalidates. */
1104
1105 th->th.th_info.ds.ds_tid = KMP_GTID_MONITOR;
1106 th->th.th_info.ds.ds_gtid = KMP_GTID_MONITOR;
1107 #if KMP_REAL_TIME_FIX
1108 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 +00001109 #else
1110 TCW_4( __kmp_global.g.g_time.dt.t_value, 0 );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001111 #endif // KMP_REAL_TIME_FIX
1112
1113 #ifdef KMP_THREAD_ATTR
1114 if ( __kmp_monitor_stksize == 0 ) {
1115 __kmp_monitor_stksize = KMP_DEFAULT_MONITOR_STKSIZE;
1116 auto_adj_size = TRUE;
1117 }
1118 status = pthread_attr_init( &thread_attr );
1119 if ( status != 0 ) {
1120 __kmp_msg(
1121 kmp_ms_fatal,
1122 KMP_MSG( CantInitThreadAttrs ),
1123 KMP_ERR( status ),
1124 __kmp_msg_null
1125 );
1126 }; // if
1127 status = pthread_attr_setdetachstate( & thread_attr, PTHREAD_CREATE_JOINABLE );
1128 if ( status != 0 ) {
1129 __kmp_msg(
1130 kmp_ms_fatal,
1131 KMP_MSG( CantSetMonitorState ),
1132 KMP_ERR( status ),
1133 __kmp_msg_null
1134 );
1135 }; // if
1136
1137 #ifdef _POSIX_THREAD_ATTR_STACKSIZE
1138 status = pthread_attr_getstacksize( & thread_attr, & size );
1139 KMP_CHECK_SYSFAIL( "pthread_attr_getstacksize", status );
1140 #else
1141 size = __kmp_sys_min_stksize;
1142 #endif /* _POSIX_THREAD_ATTR_STACKSIZE */
1143 #endif /* KMP_THREAD_ATTR */
1144
1145 if ( __kmp_monitor_stksize == 0 ) {
1146 __kmp_monitor_stksize = KMP_DEFAULT_MONITOR_STKSIZE;
1147 }
1148 if ( __kmp_monitor_stksize < __kmp_sys_min_stksize ) {
1149 __kmp_monitor_stksize = __kmp_sys_min_stksize;
1150 }
1151
1152 KA_TRACE( 10, ( "__kmp_create_monitor: default stacksize = %lu bytes,"
1153 "requested stacksize = %lu bytes\n",
1154 size, __kmp_monitor_stksize ) );
1155
1156 retry:
1157
1158 /* Set stack size for this thread now. */
1159
1160 #ifdef _POSIX_THREAD_ATTR_STACKSIZE
1161 KA_TRACE( 10, ( "__kmp_create_monitor: setting stacksize = %lu bytes,",
1162 __kmp_monitor_stksize ) );
1163 status = pthread_attr_setstacksize( & thread_attr, __kmp_monitor_stksize );
1164 if ( status != 0 ) {
1165 if ( auto_adj_size ) {
1166 __kmp_monitor_stksize *= 2;
1167 goto retry;
1168 }
1169 __kmp_msg(
1170 kmp_ms_warning, // should this be fatal? BB
1171 KMP_MSG( CantSetMonitorStackSize, (long int) __kmp_monitor_stksize ),
1172 KMP_ERR( status ),
1173 KMP_HNT( ChangeMonitorStackSize ),
1174 __kmp_msg_null
1175 );
1176 }; // if
1177 #endif /* _POSIX_THREAD_ATTR_STACKSIZE */
1178
Jim Cownie5e8470a2013-09-27 10:38:44 +00001179 status = pthread_create( &handle, & thread_attr, __kmp_launch_monitor, (void *) th );
1180
1181 if ( status != 0 ) {
1182 #ifdef _POSIX_THREAD_ATTR_STACKSIZE
1183 if ( status == EINVAL ) {
1184 if ( auto_adj_size && ( __kmp_monitor_stksize < (size_t)0x40000000 ) ) {
1185 __kmp_monitor_stksize *= 2;
1186 goto retry;
1187 }
1188 __kmp_msg(
1189 kmp_ms_fatal,
1190 KMP_MSG( CantSetMonitorStackSize, __kmp_monitor_stksize ),
1191 KMP_ERR( status ),
1192 KMP_HNT( IncreaseMonitorStackSize ),
1193 __kmp_msg_null
1194 );
1195 }; // if
1196 if ( status == ENOMEM ) {
1197 __kmp_msg(
1198 kmp_ms_fatal,
1199 KMP_MSG( CantSetMonitorStackSize, __kmp_monitor_stksize ),
1200 KMP_ERR( status ),
1201 KMP_HNT( DecreaseMonitorStackSize ),
1202 __kmp_msg_null
1203 );
1204 }; // if
1205 #endif /* _POSIX_THREAD_ATTR_STACKSIZE */
1206 if ( status == EAGAIN ) {
1207 __kmp_msg(
1208 kmp_ms_fatal,
1209 KMP_MSG( NoResourcesForMonitorThread ),
1210 KMP_ERR( status ),
1211 KMP_HNT( DecreaseNumberOfThreadsInUse ),
1212 __kmp_msg_null
1213 );
1214 }; // if
1215 KMP_SYSFAIL( "pthread_create", status );
1216 }; // if
1217
1218 th->th.th_info.ds.ds_thread = handle;
1219
1220 #if KMP_REAL_TIME_FIX
1221 // Wait for the monitor thread is really started and set its *priority*.
1222 KMP_DEBUG_ASSERT( sizeof( kmp_uint32 ) == sizeof( __kmp_global.g.g_time.dt.t_value ) );
1223 __kmp_wait_yield_4(
1224 (kmp_uint32 volatile *) & __kmp_global.g.g_time.dt.t_value, -1, & __kmp_neq_4, NULL
1225 );
1226 #endif // KMP_REAL_TIME_FIX
1227
1228 #ifdef KMP_THREAD_ATTR
1229 status = pthread_attr_destroy( & thread_attr );
1230 if ( status != 0 ) {
1231 __kmp_msg( //
1232 kmp_ms_warning,
1233 KMP_MSG( CantDestroyThreadAttrs ),
1234 KMP_ERR( status ),
1235 __kmp_msg_null
1236 );
1237 }; // if
1238 #endif
1239
1240 KMP_MB(); /* Flush all pending memory write invalidates. */
1241
1242 KA_TRACE( 10, ( "__kmp_create_monitor: monitor created %#.8lx\n", th->th.th_info.ds.ds_thread ) );
1243
1244} // __kmp_create_monitor
Jonathan Peytonb66d1aa2016-09-27 17:11:17 +00001245#endif // KMP_USE_MONITOR
Jim Cownie5e8470a2013-09-27 10:38:44 +00001246
1247void
1248__kmp_exit_thread(
1249 int exit_status
1250) {
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001251 pthread_exit( (void *)(intptr_t) exit_status );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001252} // __kmp_exit_thread
1253
Jonathan Peytonb66d1aa2016-09-27 17:11:17 +00001254#if KMP_USE_MONITOR
Jim Cownie07ea89f2014-09-03 11:10:54 +00001255void __kmp_resume_monitor();
1256
Jim Cownie5e8470a2013-09-27 10:38:44 +00001257void
1258__kmp_reap_monitor( kmp_info_t *th )
1259{
Jonathan Peyton7c4d66d2015-06-08 20:01:14 +00001260 int status;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001261 void *exit_val;
1262
1263 KA_TRACE( 10, ("__kmp_reap_monitor: try to reap monitor thread with handle %#.8lx\n",
1264 th->th.th_info.ds.ds_thread ) );
1265
1266 // If monitor has been created, its tid and gtid should be KMP_GTID_MONITOR.
1267 // If both tid and gtid are 0, it means the monitor did not ever start.
1268 // If both tid and gtid are KMP_GTID_DNE, the monitor has been shut down.
1269 KMP_DEBUG_ASSERT( th->th.th_info.ds.ds_tid == th->th.th_info.ds.ds_gtid );
1270 if ( th->th.th_info.ds.ds_gtid != KMP_GTID_MONITOR ) {
Jonathan Peyton4fee5f62015-12-18 23:20:36 +00001271 KA_TRACE( 10, ("__kmp_reap_monitor: monitor did not start, returning\n") );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001272 return;
1273 }; // if
1274
1275 KMP_MB(); /* Flush all pending memory write invalidates. */
1276
1277
Jonathan Peyton93495de2016-06-13 17:36:40 +00001278 /* First, check to see whether the monitor thread exists to wake it up. This is
1279 to avoid performance problem when the monitor sleeps during blocktime-size
1280 interval */
Jim Cownie5e8470a2013-09-27 10:38:44 +00001281
1282 status = pthread_kill( th->th.th_info.ds.ds_thread, 0 );
Jonathan Peyton93495de2016-06-13 17:36:40 +00001283 if (status != ESRCH) {
Jim Cownie07ea89f2014-09-03 11:10:54 +00001284 __kmp_resume_monitor(); // Wake up the monitor thread
Jonathan Peyton93495de2016-06-13 17:36:40 +00001285 }
1286 KA_TRACE( 10, ("__kmp_reap_monitor: try to join with monitor\n") );
1287 status = pthread_join( th->th.th_info.ds.ds_thread, & exit_val);
1288 if (exit_val != th) {
1289 __kmp_msg(
1290 kmp_ms_fatal,
1291 KMP_MSG( ReapMonitorError ),
1292 KMP_ERR( status ),
1293 __kmp_msg_null
1294 );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001295 }
1296
1297 th->th.th_info.ds.ds_tid = KMP_GTID_DNE;
1298 th->th.th_info.ds.ds_gtid = KMP_GTID_DNE;
1299
1300 KA_TRACE( 10, ("__kmp_reap_monitor: done reaping monitor thread with handle %#.8lx\n",
1301 th->th.th_info.ds.ds_thread ) );
1302
1303 KMP_MB(); /* Flush all pending memory write invalidates. */
1304
1305}
Jonathan Peytonb66d1aa2016-09-27 17:11:17 +00001306#endif // KMP_USE_MONITOR
Jim Cownie5e8470a2013-09-27 10:38:44 +00001307
1308void
1309__kmp_reap_worker( kmp_info_t *th )
1310{
1311 int status;
1312 void *exit_val;
1313
1314 KMP_MB(); /* Flush all pending memory write invalidates. */
1315
1316 KA_TRACE( 10, ("__kmp_reap_worker: try to reap T#%d\n", th->th.th_info.ds.ds_gtid ) );
1317
Jonathan Peyton93495de2016-06-13 17:36:40 +00001318 status = pthread_join( th->th.th_info.ds.ds_thread, & exit_val);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001319#ifdef KMP_DEBUG
Jonathan Peyton93495de2016-06-13 17:36:40 +00001320 /* Don't expose these to the user until we understand when they trigger */
1321 if ( status != 0 ) {
1322 __kmp_msg(kmp_ms_fatal, KMP_MSG( ReapWorkerError ), KMP_ERR( status ), __kmp_msg_null);
Jonathan Peyton749b4d52016-01-27 21:02:04 +00001323 }
Jonathan Peyton93495de2016-06-13 17:36:40 +00001324 if ( exit_val != th ) {
1325 KA_TRACE( 10, ( "__kmp_reap_worker: worker T#%d did not reap properly, exit_val = %p\n",
1326 th->th.th_info.ds.ds_gtid, exit_val ) );
1327 }
1328#endif /* KMP_DEBUG */
Jim Cownie5e8470a2013-09-27 10:38:44 +00001329
1330 KA_TRACE( 10, ("__kmp_reap_worker: done reaping T#%d\n", th->th.th_info.ds.ds_gtid ) );
1331
1332 KMP_MB(); /* Flush all pending memory write invalidates. */
1333}
1334
1335
1336/* ------------------------------------------------------------------------ */
1337/* ------------------------------------------------------------------------ */
1338
1339#if KMP_HANDLE_SIGNALS
1340
1341
1342static void
1343__kmp_null_handler( int signo )
1344{
1345 // Do nothing, for doing SIG_IGN-type actions.
1346} // __kmp_null_handler
1347
1348
1349static void
1350__kmp_team_handler( int signo )
1351{
1352 if ( __kmp_global.g.g_abort == 0 ) {
1353 /* Stage 1 signal handler, let's shut down all of the threads */
1354 #ifdef KMP_DEBUG
1355 __kmp_debug_printf( "__kmp_team_handler: caught signal = %d\n", signo );
1356 #endif
1357 switch ( signo ) {
1358 case SIGHUP :
1359 case SIGINT :
1360 case SIGQUIT :
1361 case SIGILL :
1362 case SIGABRT :
1363 case SIGFPE :
1364 case SIGBUS :
1365 case SIGSEGV :
1366 #ifdef SIGSYS
1367 case SIGSYS :
1368 #endif
1369 case SIGTERM :
1370 if ( __kmp_debug_buf ) {
1371 __kmp_dump_debug_buffer( );
1372 }; // if
1373 KMP_MB(); // Flush all pending memory write invalidates.
1374 TCW_4( __kmp_global.g.g_abort, signo );
1375 KMP_MB(); // Flush all pending memory write invalidates.
1376 TCW_4( __kmp_global.g.g_done, TRUE );
1377 KMP_MB(); // Flush all pending memory write invalidates.
1378 break;
1379 default:
1380 #ifdef KMP_DEBUG
1381 __kmp_debug_printf( "__kmp_team_handler: unknown signal type" );
1382 #endif
1383 break;
1384 }; // switch
1385 }; // if
1386} // __kmp_team_handler
1387
1388
1389static
1390void __kmp_sigaction( int signum, const struct sigaction * act, struct sigaction * oldact ) {
1391 int rc = sigaction( signum, act, oldact );
1392 KMP_CHECK_SYSFAIL_ERRNO( "sigaction", rc );
1393}
1394
1395
1396static void
1397__kmp_install_one_handler( int sig, sig_func_t handler_func, int parallel_init )
1398{
1399 KMP_MB(); // Flush all pending memory write invalidates.
1400 KB_TRACE( 60, ( "__kmp_install_one_handler( %d, ..., %d )\n", sig, parallel_init ) );
1401 if ( parallel_init ) {
1402 struct sigaction new_action;
1403 struct sigaction old_action;
1404 new_action.sa_handler = handler_func;
1405 new_action.sa_flags = 0;
1406 sigfillset( & new_action.sa_mask );
1407 __kmp_sigaction( sig, & new_action, & old_action );
1408 if ( old_action.sa_handler == __kmp_sighldrs[ sig ].sa_handler ) {
1409 sigaddset( & __kmp_sigset, sig );
1410 } else {
1411 // Restore/keep user's handler if one previously installed.
1412 __kmp_sigaction( sig, & old_action, NULL );
1413 }; // if
1414 } else {
1415 // Save initial/system signal handlers to see if user handlers installed.
1416 __kmp_sigaction( sig, NULL, & __kmp_sighldrs[ sig ] );
1417 }; // if
1418 KMP_MB(); // Flush all pending memory write invalidates.
1419} // __kmp_install_one_handler
1420
1421
1422static void
1423__kmp_remove_one_handler( int sig )
1424{
1425 KB_TRACE( 60, ( "__kmp_remove_one_handler( %d )\n", sig ) );
1426 if ( sigismember( & __kmp_sigset, sig ) ) {
1427 struct sigaction old;
1428 KMP_MB(); // Flush all pending memory write invalidates.
1429 __kmp_sigaction( sig, & __kmp_sighldrs[ sig ], & old );
1430 if ( ( old.sa_handler != __kmp_team_handler ) && ( old.sa_handler != __kmp_null_handler ) ) {
1431 // Restore the users signal handler.
1432 KB_TRACE( 10, ( "__kmp_remove_one_handler: oops, not our handler, restoring: sig=%d\n", sig ) );
1433 __kmp_sigaction( sig, & old, NULL );
1434 }; // if
1435 sigdelset( & __kmp_sigset, sig );
1436 KMP_MB(); // Flush all pending memory write invalidates.
1437 }; // if
1438} // __kmp_remove_one_handler
1439
1440
1441void
1442__kmp_install_signals( int parallel_init )
1443{
1444 KB_TRACE( 10, ( "__kmp_install_signals( %d )\n", parallel_init ) );
1445 if ( __kmp_handle_signals || ! parallel_init ) {
1446 // If ! parallel_init, we do not install handlers, just save original handlers.
1447 // Let us do it even __handle_signals is 0.
1448 sigemptyset( & __kmp_sigset );
1449 __kmp_install_one_handler( SIGHUP, __kmp_team_handler, parallel_init );
1450 __kmp_install_one_handler( SIGINT, __kmp_team_handler, parallel_init );
1451 __kmp_install_one_handler( SIGQUIT, __kmp_team_handler, parallel_init );
1452 __kmp_install_one_handler( SIGILL, __kmp_team_handler, parallel_init );
1453 __kmp_install_one_handler( SIGABRT, __kmp_team_handler, parallel_init );
1454 __kmp_install_one_handler( SIGFPE, __kmp_team_handler, parallel_init );
1455 __kmp_install_one_handler( SIGBUS, __kmp_team_handler, parallel_init );
1456 __kmp_install_one_handler( SIGSEGV, __kmp_team_handler, parallel_init );
1457 #ifdef SIGSYS
1458 __kmp_install_one_handler( SIGSYS, __kmp_team_handler, parallel_init );
1459 #endif // SIGSYS
1460 __kmp_install_one_handler( SIGTERM, __kmp_team_handler, parallel_init );
1461 #ifdef SIGPIPE
1462 __kmp_install_one_handler( SIGPIPE, __kmp_team_handler, parallel_init );
1463 #endif // SIGPIPE
1464 }; // if
1465} // __kmp_install_signals
1466
1467
1468void
1469__kmp_remove_signals( void )
1470{
1471 int sig;
1472 KB_TRACE( 10, ( "__kmp_remove_signals()\n" ) );
1473 for ( sig = 1; sig < NSIG; ++ sig ) {
1474 __kmp_remove_one_handler( sig );
1475 }; // for sig
1476} // __kmp_remove_signals
1477
1478
1479#endif // KMP_HANDLE_SIGNALS
1480
1481/* ------------------------------------------------------------------------ */
1482/* ------------------------------------------------------------------------ */
1483
1484void
1485__kmp_enable( int new_state )
1486{
1487 #ifdef KMP_CANCEL_THREADS
1488 int status, old_state;
1489 status = pthread_setcancelstate( new_state, & old_state );
1490 KMP_CHECK_SYSFAIL( "pthread_setcancelstate", status );
1491 KMP_DEBUG_ASSERT( old_state == PTHREAD_CANCEL_DISABLE );
1492 #endif
1493}
1494
1495void
1496__kmp_disable( int * old_state )
1497{
1498 #ifdef KMP_CANCEL_THREADS
1499 int status;
1500 status = pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, old_state );
1501 KMP_CHECK_SYSFAIL( "pthread_setcancelstate", status );
1502 #endif
1503}
1504
1505/* ------------------------------------------------------------------------ */
1506/* ------------------------------------------------------------------------ */
1507
1508static void
1509__kmp_atfork_prepare (void)
1510{
1511 /* nothing to do */
1512}
1513
1514static void
1515__kmp_atfork_parent (void)
1516{
1517 /* nothing to do */
1518}
1519
1520/*
1521 Reset the library so execution in the child starts "all over again" with
1522 clean data structures in initial states. Don't worry about freeing memory
1523 allocated by parent, just abandon it to be safe.
1524*/
1525static void
1526__kmp_atfork_child (void)
1527{
1528 /* TODO make sure this is done right for nested/sibling */
1529 // ATT: Memory leaks are here? TODO: Check it and fix.
1530 /* KMP_ASSERT( 0 ); */
1531
1532 ++__kmp_fork_count;
1533
1534 __kmp_init_runtime = FALSE;
Jonathan Peytonb66d1aa2016-09-27 17:11:17 +00001535#if KMP_USE_MONITOR
Jim Cownie5e8470a2013-09-27 10:38:44 +00001536 __kmp_init_monitor = 0;
Jonathan Peytonb66d1aa2016-09-27 17:11:17 +00001537#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +00001538 __kmp_init_parallel = FALSE;
1539 __kmp_init_middle = FALSE;
1540 __kmp_init_serial = FALSE;
1541 TCW_4(__kmp_init_gtid, FALSE);
1542 __kmp_init_common = FALSE;
1543
1544 TCW_4(__kmp_init_user_locks, FALSE);
Andrey Churbanov5c56fb52015-02-20 18:05:17 +00001545#if ! KMP_USE_DYNAMIC_LOCK
Jim Cownie07ea89f2014-09-03 11:10:54 +00001546 __kmp_user_lock_table.used = 1;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001547 __kmp_user_lock_table.allocated = 0;
1548 __kmp_user_lock_table.table = NULL;
1549 __kmp_lock_blocks = NULL;
Andrey Churbanov5c56fb52015-02-20 18:05:17 +00001550#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +00001551
1552 __kmp_all_nth = 0;
1553 TCW_4(__kmp_nth, 0);
1554
1555 /* Must actually zero all the *cache arguments passed to __kmpc_threadprivate here
1556 so threadprivate doesn't use stale data */
1557 KA_TRACE( 10, ( "__kmp_atfork_child: checking cache address list %p\n",
1558 __kmp_threadpriv_cache_list ) );
1559
1560 while ( __kmp_threadpriv_cache_list != NULL ) {
1561
1562 if ( *__kmp_threadpriv_cache_list -> addr != NULL ) {
1563 KC_TRACE( 50, ( "__kmp_atfork_child: zeroing cache at address %p\n",
1564 &(*__kmp_threadpriv_cache_list -> addr) ) );
1565
1566 *__kmp_threadpriv_cache_list -> addr = NULL;
1567 }
1568 __kmp_threadpriv_cache_list = __kmp_threadpriv_cache_list -> next;
1569 }
1570
1571 __kmp_init_runtime = FALSE;
1572
1573 /* reset statically initialized locks */
1574 __kmp_init_bootstrap_lock( &__kmp_initz_lock );
1575 __kmp_init_bootstrap_lock( &__kmp_stdio_lock );
1576 __kmp_init_bootstrap_lock( &__kmp_console_lock );
1577
1578 /* This is necessary to make sure no stale data is left around */
1579 /* AC: customers complain that we use unsafe routines in the atfork
1580 handler. Mathworks: dlsym() is unsafe. We call dlsym and dlopen
1581 in dynamic_link when check the presence of shared tbbmalloc library.
1582 Suggestion is to make the library initialization lazier, similar
1583 to what done for __kmpc_begin(). */
1584 // TODO: synchronize all static initializations with regular library
1585 // startup; look at kmp_global.c and etc.
1586 //__kmp_internal_begin ();
1587
1588}
1589
1590void
1591__kmp_register_atfork(void) {
1592 if ( __kmp_need_register_atfork ) {
1593 int status = pthread_atfork( __kmp_atfork_prepare, __kmp_atfork_parent, __kmp_atfork_child );
1594 KMP_CHECK_SYSFAIL( "pthread_atfork", status );
1595 __kmp_need_register_atfork = FALSE;
1596 }
1597}
1598
1599void
1600__kmp_suspend_initialize( void )
1601{
1602 int status;
1603 status = pthread_mutexattr_init( &__kmp_suspend_mutex_attr );
1604 KMP_CHECK_SYSFAIL( "pthread_mutexattr_init", status );
1605 status = pthread_condattr_init( &__kmp_suspend_cond_attr );
1606 KMP_CHECK_SYSFAIL( "pthread_condattr_init", status );
1607}
1608
1609static void
1610__kmp_suspend_initialize_thread( kmp_info_t *th )
1611{
1612 if ( th->th.th_suspend_init_count <= __kmp_fork_count ) {
1613 /* this means we haven't initialized the suspension pthread objects for this thread
1614 in this instance of the process */
1615 int status;
1616 status = pthread_cond_init( &th->th.th_suspend_cv.c_cond, &__kmp_suspend_cond_attr );
1617 KMP_CHECK_SYSFAIL( "pthread_cond_init", status );
1618 status = pthread_mutex_init( &th->th.th_suspend_mx.m_mutex, & __kmp_suspend_mutex_attr );
1619 KMP_CHECK_SYSFAIL( "pthread_mutex_init", status );
1620 *(volatile int*)&th->th.th_suspend_init_count = __kmp_fork_count + 1;
1621 };
1622}
1623
1624void
1625__kmp_suspend_uninitialize_thread( kmp_info_t *th )
1626{
1627 if(th->th.th_suspend_init_count > __kmp_fork_count) {
1628 /* this means we have initialize the suspension pthread objects for this thread
1629 in this instance of the process */
1630 int status;
1631
1632 status = pthread_cond_destroy( &th->th.th_suspend_cv.c_cond );
1633 if ( status != 0 && status != EBUSY ) {
1634 KMP_SYSFAIL( "pthread_cond_destroy", status );
1635 };
1636 status = pthread_mutex_destroy( &th->th.th_suspend_mx.m_mutex );
1637 if ( status != 0 && status != EBUSY ) {
1638 KMP_SYSFAIL( "pthread_mutex_destroy", status );
1639 };
1640 --th->th.th_suspend_init_count;
1641 KMP_DEBUG_ASSERT(th->th.th_suspend_init_count == __kmp_fork_count);
1642 }
1643}
1644
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001645/* This routine puts the calling thread to sleep after setting the
1646 * sleep bit for the indicated flag variable to true.
Jim Cownie5e8470a2013-09-27 10:38:44 +00001647 */
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001648template <class C>
1649static inline void __kmp_suspend_template( int th_gtid, C *flag )
Jim Cownie5e8470a2013-09-27 10:38:44 +00001650{
Jonathan Peyton45be4502015-08-11 21:36:41 +00001651 KMP_TIME_DEVELOPER_BLOCK(USER_suspend);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001652 kmp_info_t *th = __kmp_threads[th_gtid];
1653 int status;
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001654 typename C::flag_t old_spin;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001655
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001656 KF_TRACE( 30, ("__kmp_suspend_template: T#%d enter for flag = %p\n", th_gtid, flag->get() ) );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001657
1658 __kmp_suspend_initialize_thread( th );
1659
1660 status = pthread_mutex_lock( &th->th.th_suspend_mx.m_mutex );
1661 KMP_CHECK_SYSFAIL( "pthread_mutex_lock", status );
1662
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001663 KF_TRACE( 10, ( "__kmp_suspend_template: T#%d setting sleep bit for spin(%p)\n",
1664 th_gtid, flag->get() ) );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001665
1666 /* TODO: shouldn't this use release semantics to ensure that __kmp_suspend_initialize_thread
1667 gets called first?
1668 */
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001669 old_spin = flag->set_sleeping();
Jim Cownie5e8470a2013-09-27 10:38:44 +00001670
Jonathan Peytone03b62f2015-10-08 18:49:40 +00001671 KF_TRACE( 5, ( "__kmp_suspend_template: T#%d set sleep bit for spin(%p)==%x, was %x\n",
1672 th_gtid, flag->get(), *(flag->get()), old_spin ) );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001673
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001674 if ( flag->done_check_val(old_spin) ) {
1675 old_spin = flag->unset_sleeping();
1676 KF_TRACE( 5, ( "__kmp_suspend_template: T#%d false alarm, reset sleep bit for spin(%p)\n",
1677 th_gtid, flag->get()) );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001678 } else {
Jim Cownie5e8470a2013-09-27 10:38:44 +00001679 /* Encapsulate in a loop as the documentation states that this may
1680 * "with low probability" return when the condition variable has
1681 * not been signaled or broadcast
1682 */
1683 int deactivated = FALSE;
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001684 TCW_PTR(th->th.th_sleep_loc, (void *)flag);
1685 while ( flag->is_sleeping() ) {
Jim Cownie5e8470a2013-09-27 10:38:44 +00001686#ifdef DEBUG_SUSPEND
1687 char buffer[128];
1688 __kmp_suspend_count++;
1689 __kmp_print_cond( buffer, &th->th.th_suspend_cv );
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001690 __kmp_printf( "__kmp_suspend_template: suspending T#%d: %s\n", th_gtid, buffer );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001691#endif
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001692 // Mark the thread as no longer active (only in the first iteration of the loop).
Jim Cownie5e8470a2013-09-27 10:38:44 +00001693 if ( ! deactivated ) {
1694 th->th.th_active = FALSE;
1695 if ( th->th.th_active_in_pool ) {
1696 th->th.th_active_in_pool = FALSE;
1697 KMP_TEST_THEN_DEC32(
1698 (kmp_int32 *) &__kmp_thread_pool_active_nth );
1699 KMP_DEBUG_ASSERT( TCR_4(__kmp_thread_pool_active_nth) >= 0 );
1700 }
1701 deactivated = TRUE;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001702 }
1703
1704#if USE_SUSPEND_TIMEOUT
1705 struct timespec now;
1706 struct timeval tval;
1707 int msecs;
1708
1709 status = gettimeofday( &tval, NULL );
1710 KMP_CHECK_SYSFAIL_ERRNO( "gettimeofday", status );
1711 TIMEVAL_TO_TIMESPEC( &tval, &now );
1712
1713 msecs = (4*__kmp_dflt_blocktime) + 200;
1714 now.tv_sec += msecs / 1000;
1715 now.tv_nsec += (msecs % 1000)*1000;
1716
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001717 KF_TRACE( 15, ( "__kmp_suspend_template: T#%d about to perform pthread_cond_timedwait\n",
Jim Cownie5e8470a2013-09-27 10:38:44 +00001718 th_gtid ) );
1719 status = pthread_cond_timedwait( &th->th.th_suspend_cv.c_cond, &th->th.th_suspend_mx.m_mutex, & now );
1720#else
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001721 KF_TRACE( 15, ( "__kmp_suspend_template: T#%d about to perform pthread_cond_wait\n",
Jonathan Peyton1bd61b42015-10-08 19:44:16 +00001722 th_gtid ) );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001723 status = pthread_cond_wait( &th->th.th_suspend_cv.c_cond, &th->th.th_suspend_mx.m_mutex );
1724#endif
1725
1726 if ( (status != 0) && (status != EINTR) && (status != ETIMEDOUT) ) {
1727 KMP_SYSFAIL( "pthread_cond_wait", status );
1728 }
1729#ifdef KMP_DEBUG
1730 if (status == ETIMEDOUT) {
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001731 if ( flag->is_sleeping() ) {
1732 KF_TRACE( 100, ( "__kmp_suspend_template: T#%d timeout wakeup\n", th_gtid ) );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001733 } else {
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001734 KF_TRACE( 2, ( "__kmp_suspend_template: T#%d timeout wakeup, sleep bit not set!\n",
Jim Cownie5e8470a2013-09-27 10:38:44 +00001735 th_gtid ) );
1736 }
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001737 } else if ( flag->is_sleeping() ) {
1738 KF_TRACE( 100, ( "__kmp_suspend_template: T#%d spurious wakeup\n", th_gtid ) );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001739 }
1740#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +00001741 } // while
1742
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001743 // Mark the thread as active again (if it was previous marked as inactive)
Jim Cownie5e8470a2013-09-27 10:38:44 +00001744 if ( deactivated ) {
1745 th->th.th_active = TRUE;
1746 if ( TCR_4(th->th.th_in_pool) ) {
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001747 KMP_TEST_THEN_INC32( (kmp_int32 *) &__kmp_thread_pool_active_nth );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001748 th->th.th_active_in_pool = TRUE;
1749 }
1750 }
1751 }
1752
1753#ifdef DEBUG_SUSPEND
1754 {
1755 char buffer[128];
1756 __kmp_print_cond( buffer, &th->th.th_suspend_cv);
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001757 __kmp_printf( "__kmp_suspend_template: T#%d has awakened: %s\n", th_gtid, buffer );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001758 }
1759#endif
1760
Jim Cownie5e8470a2013-09-27 10:38:44 +00001761 status = pthread_mutex_unlock( &th->th.th_suspend_mx.m_mutex );
1762 KMP_CHECK_SYSFAIL( "pthread_mutex_unlock", status );
1763
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001764 KF_TRACE( 30, ("__kmp_suspend_template: T#%d exit\n", th_gtid ) );
1765}
1766
1767void __kmp_suspend_32(int th_gtid, kmp_flag_32 *flag) {
1768 __kmp_suspend_template(th_gtid, flag);
1769}
1770void __kmp_suspend_64(int th_gtid, kmp_flag_64 *flag) {
1771 __kmp_suspend_template(th_gtid, flag);
1772}
1773void __kmp_suspend_oncore(int th_gtid, kmp_flag_oncore *flag) {
1774 __kmp_suspend_template(th_gtid, flag);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001775}
1776
1777
1778/* This routine signals the thread specified by target_gtid to wake up
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001779 * after setting the sleep bit indicated by the flag argument to FALSE.
1780 * The target thread must already have called __kmp_suspend_template()
Jim Cownie5e8470a2013-09-27 10:38:44 +00001781 */
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001782template <class C>
1783static inline void __kmp_resume_template( int target_gtid, C *flag )
Jim Cownie5e8470a2013-09-27 10:38:44 +00001784{
Jonathan Peyton45be4502015-08-11 21:36:41 +00001785 KMP_TIME_DEVELOPER_BLOCK(USER_resume);
Jim Cownie5e8470a2013-09-27 10:38:44 +00001786 kmp_info_t *th = __kmp_threads[target_gtid];
1787 int status;
Jim Cownie5e8470a2013-09-27 10:38:44 +00001788
1789#ifdef KMP_DEBUG
1790 int gtid = TCR_4(__kmp_init_gtid) ? __kmp_get_gtid() : -1;
1791#endif
1792
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001793 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 +00001794 KMP_DEBUG_ASSERT( gtid != target_gtid );
1795
1796 __kmp_suspend_initialize_thread( th );
1797
1798 status = pthread_mutex_lock( &th->th.th_suspend_mx.m_mutex );
1799 KMP_CHECK_SYSFAIL( "pthread_mutex_lock", status );
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001800
Jonathan Peyton3f5dfc22015-11-09 16:31:51 +00001801 if (!flag) { // coming from __kmp_null_resume_wrapper
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001802 flag = (C *)th->th.th_sleep_loc;
1803 }
1804
Jonathan Peyton3f5dfc22015-11-09 16:31:51 +00001805 // First, check if the flag is null or its type has changed. If so, someone else woke it up.
1806 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 +00001807 KF_TRACE( 5, ( "__kmp_resume_template: T#%d exiting, thread T#%d already awake: flag(%p)\n",
1808 gtid, target_gtid, NULL ) );
1809 status = pthread_mutex_unlock( &th->th.th_suspend_mx.m_mutex );
1810 KMP_CHECK_SYSFAIL( "pthread_mutex_unlock", status );
1811 return;
1812 }
Jonathan Peyton1bd61b42015-10-08 19:44:16 +00001813 else { // if multiple threads are sleeping, flag should be internally referring to a specific thread here
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001814 typename C::flag_t old_spin = flag->unset_sleeping();
1815 if ( ! flag->is_sleeping_val(old_spin) ) {
1816 KF_TRACE( 5, ( "__kmp_resume_template: T#%d exiting, thread T#%d already awake: flag(%p): "
1817 "%u => %u\n",
1818 gtid, target_gtid, flag->get(), old_spin, *flag->get() ) );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001819 status = pthread_mutex_unlock( &th->th.th_suspend_mx.m_mutex );
1820 KMP_CHECK_SYSFAIL( "pthread_mutex_unlock", status );
1821 return;
1822 }
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001823 KF_TRACE( 5, ( "__kmp_resume_template: T#%d about to wakeup T#%d, reset sleep bit for flag's loc(%p): "
1824 "%u => %u\n",
1825 gtid, target_gtid, flag->get(), old_spin, *flag->get() ) );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001826 }
1827 TCW_PTR(th->th.th_sleep_loc, NULL);
1828
Jim Cownie5e8470a2013-09-27 10:38:44 +00001829
1830#ifdef DEBUG_SUSPEND
1831 {
1832 char buffer[128];
1833 __kmp_print_cond( buffer, &th->th.th_suspend_cv );
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001834 __kmp_printf( "__kmp_resume_template: T#%d resuming T#%d: %s\n", gtid, target_gtid, buffer );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001835 }
1836#endif
1837
Jim Cownie5e8470a2013-09-27 10:38:44 +00001838 status = pthread_cond_signal( &th->th.th_suspend_cv.c_cond );
1839 KMP_CHECK_SYSFAIL( "pthread_cond_signal", status );
1840 status = pthread_mutex_unlock( &th->th.th_suspend_mx.m_mutex );
1841 KMP_CHECK_SYSFAIL( "pthread_mutex_unlock", status );
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001842 KF_TRACE( 30, ( "__kmp_resume_template: T#%d exiting after signaling wake up for T#%d\n",
Jim Cownie5e8470a2013-09-27 10:38:44 +00001843 gtid, target_gtid ) );
1844}
1845
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001846void __kmp_resume_32(int target_gtid, kmp_flag_32 *flag) {
1847 __kmp_resume_template(target_gtid, flag);
1848}
1849void __kmp_resume_64(int target_gtid, kmp_flag_64 *flag) {
1850 __kmp_resume_template(target_gtid, flag);
1851}
1852void __kmp_resume_oncore(int target_gtid, kmp_flag_oncore *flag) {
1853 __kmp_resume_template(target_gtid, flag);
1854}
1855
Jonathan Peytonb66d1aa2016-09-27 17:11:17 +00001856#if KMP_USE_MONITOR
Jim Cownie07ea89f2014-09-03 11:10:54 +00001857void
1858__kmp_resume_monitor()
1859{
Jonathan Peyton11dc82f2016-05-05 16:15:57 +00001860 KMP_TIME_DEVELOPER_BLOCK(USER_resume);
Jim Cownie07ea89f2014-09-03 11:10:54 +00001861 int status;
1862#ifdef KMP_DEBUG
1863 int gtid = TCR_4(__kmp_init_gtid) ? __kmp_get_gtid() : -1;
1864 KF_TRACE( 30, ( "__kmp_resume_monitor: T#%d wants to wakeup T#%d enter\n",
1865 gtid, KMP_GTID_MONITOR ) );
1866 KMP_DEBUG_ASSERT( gtid != KMP_GTID_MONITOR );
1867#endif
1868 status = pthread_mutex_lock( &__kmp_wait_mx.m_mutex );
1869 KMP_CHECK_SYSFAIL( "pthread_mutex_lock", status );
1870#ifdef DEBUG_SUSPEND
1871 {
1872 char buffer[128];
1873 __kmp_print_cond( buffer, &__kmp_wait_cv.c_cond );
1874 __kmp_printf( "__kmp_resume_monitor: T#%d resuming T#%d: %s\n", gtid, KMP_GTID_MONITOR, buffer );
1875 }
1876#endif
1877 status = pthread_cond_signal( &__kmp_wait_cv.c_cond );
1878 KMP_CHECK_SYSFAIL( "pthread_cond_signal", status );
1879 status = pthread_mutex_unlock( &__kmp_wait_mx.m_mutex );
1880 KMP_CHECK_SYSFAIL( "pthread_mutex_unlock", status );
1881 KF_TRACE( 30, ( "__kmp_resume_monitor: T#%d exiting after signaling wake up for T#%d\n",
1882 gtid, KMP_GTID_MONITOR ) );
1883}
Jonathan Peytonb66d1aa2016-09-27 17:11:17 +00001884#endif // KMP_USE_MONITOR
Jim Cownie5e8470a2013-09-27 10:38:44 +00001885
1886/* ------------------------------------------------------------------------ */
1887/* ------------------------------------------------------------------------ */
1888
1889void
1890__kmp_yield( int cond )
1891{
Jonathan Peytonb66d1aa2016-09-27 17:11:17 +00001892 if (cond
1893#if KMP_USE_MONITOR
1894 && __kmp_yielding_on
1895#endif
1896 ) {
Jim Cownie5e8470a2013-09-27 10:38:44 +00001897 sched_yield();
1898 }
1899}
1900
1901/* ------------------------------------------------------------------------ */
1902/* ------------------------------------------------------------------------ */
1903
1904void
1905__kmp_gtid_set_specific( int gtid )
1906{
Jonathan Peytonf2520102016-04-18 21:33:01 +00001907 if( __kmp_init_gtid ) {
1908 int status;
1909 status = pthread_setspecific( __kmp_gtid_threadprivate_key, (void*)(intptr_t)(gtid+1) );
1910 KMP_CHECK_SYSFAIL( "pthread_setspecific", status );
1911 } else {
1912 KA_TRACE( 50, ("__kmp_gtid_set_specific: runtime shutdown, returning\n" ) );
1913 }
Jim Cownie5e8470a2013-09-27 10:38:44 +00001914}
1915
1916int
1917__kmp_gtid_get_specific()
1918{
1919 int gtid;
Jonathan Peytonf2520102016-04-18 21:33:01 +00001920 if ( !__kmp_init_gtid ) {
1921 KA_TRACE( 50, ("__kmp_gtid_get_specific: runtime shutdown, returning KMP_GTID_SHUTDOWN\n" ) );
Jim Cownie5e8470a2013-09-27 10:38:44 +00001922 return KMP_GTID_SHUTDOWN;
1923 }
1924 gtid = (int)(size_t)pthread_getspecific( __kmp_gtid_threadprivate_key );
1925 if ( gtid == 0 ) {
1926 gtid = KMP_GTID_DNE;
1927 }
1928 else {
1929 gtid--;
1930 }
1931 KA_TRACE( 50, ("__kmp_gtid_get_specific: key:%d gtid:%d\n",
1932 __kmp_gtid_threadprivate_key, gtid ));
1933 return gtid;
1934}
1935
1936/* ------------------------------------------------------------------------ */
1937/* ------------------------------------------------------------------------ */
1938
1939double
1940__kmp_read_cpu_time( void )
1941{
1942 /*clock_t t;*/
1943 struct tms buffer;
1944
1945 /*t =*/ times( & buffer );
1946
1947 return (buffer.tms_utime + buffer.tms_cutime) / (double) CLOCKS_PER_SEC;
1948}
1949
1950int
1951__kmp_read_system_info( struct kmp_sys_info *info )
1952{
1953 int status;
1954 struct rusage r_usage;
1955
1956 memset( info, 0, sizeof( *info ) );
1957
1958 status = getrusage( RUSAGE_SELF, &r_usage);
1959 KMP_CHECK_SYSFAIL_ERRNO( "getrusage", status );
1960
1961 info->maxrss = r_usage.ru_maxrss; /* the maximum resident set size utilized (in kilobytes) */
1962 info->minflt = r_usage.ru_minflt; /* the number of page faults serviced without any I/O */
1963 info->majflt = r_usage.ru_majflt; /* the number of page faults serviced that required I/O */
1964 info->nswap = r_usage.ru_nswap; /* the number of times a process was "swapped" out of memory */
1965 info->inblock = r_usage.ru_inblock; /* the number of times the file system had to perform input */
1966 info->oublock = r_usage.ru_oublock; /* the number of times the file system had to perform output */
1967 info->nvcsw = r_usage.ru_nvcsw; /* the number of times a context switch was voluntarily */
1968 info->nivcsw = r_usage.ru_nivcsw; /* the number of times a context switch was forced */
1969
1970 return (status != 0);
1971}
1972
1973/* ------------------------------------------------------------------------ */
1974/* ------------------------------------------------------------------------ */
1975
Jim Cownie5e8470a2013-09-27 10:38:44 +00001976void
1977__kmp_read_system_time( double *delta )
1978{
1979 double t_ns;
1980 struct timeval tval;
1981 struct timespec stop;
1982 int status;
1983
1984 status = gettimeofday( &tval, NULL );
1985 KMP_CHECK_SYSFAIL_ERRNO( "gettimeofday", status );
1986 TIMEVAL_TO_TIMESPEC( &tval, &stop );
1987 t_ns = TS2NS(stop) - TS2NS(__kmp_sys_timer_data.start);
1988 *delta = (t_ns * 1e-9);
1989}
1990
1991void
1992__kmp_clear_system_time( void )
1993{
1994 struct timeval tval;
1995 int status;
1996 status = gettimeofday( &tval, NULL );
1997 KMP_CHECK_SYSFAIL_ERRNO( "gettimeofday", status );
1998 TIMEVAL_TO_TIMESPEC( &tval, &__kmp_sys_timer_data.start );
1999}
2000
2001/* ------------------------------------------------------------------------ */
2002/* ------------------------------------------------------------------------ */
2003
2004#ifdef BUILD_TV
2005
2006void
2007__kmp_tv_threadprivate_store( kmp_info_t *th, void *global_addr, void *thread_addr )
2008{
2009 struct tv_data *p;
2010
2011 p = (struct tv_data *) __kmp_allocate( sizeof( *p ) );
2012
2013 p->u.tp.global_addr = global_addr;
2014 p->u.tp.thread_addr = thread_addr;
2015
2016 p->type = (void *) 1;
2017
2018 p->next = th->th.th_local.tv_data;
2019 th->th.th_local.tv_data = p;
2020
2021 if ( p->next == 0 ) {
2022 int rc = pthread_setspecific( __kmp_tv_key, p );
2023 KMP_CHECK_SYSFAIL( "pthread_setspecific", rc );
2024 }
2025}
2026
2027#endif /* BUILD_TV */
2028
2029/* ------------------------------------------------------------------------ */
2030/* ------------------------------------------------------------------------ */
2031
2032static int
2033__kmp_get_xproc( void ) {
2034
2035 int r = 0;
2036
Joerg Sonnenberger7649cd42015-09-21 20:29:12 +00002037 #if KMP_OS_LINUX || KMP_OS_FREEBSD || KMP_OS_NETBSD
Jim Cownie5e8470a2013-09-27 10:38:44 +00002038
2039 r = sysconf( _SC_NPROCESSORS_ONLN );
2040
2041 #elif KMP_OS_DARWIN
2042
2043 // Bug C77011 High "OpenMP Threads and number of active cores".
2044
2045 // Find the number of available CPUs.
2046 kern_return_t rc;
2047 host_basic_info_data_t info;
2048 mach_msg_type_number_t num = HOST_BASIC_INFO_COUNT;
2049 rc = host_info( mach_host_self(), HOST_BASIC_INFO, (host_info_t) & info, & num );
2050 if ( rc == 0 && num == HOST_BASIC_INFO_COUNT ) {
2051 // Cannot use KA_TRACE() here because this code works before trace support is
2052 // initialized.
2053 r = info.avail_cpus;
2054 } else {
2055 KMP_WARNING( CantGetNumAvailCPU );
2056 KMP_INFORM( AssumedNumCPU );
2057 }; // if
2058
2059 #else
2060
2061 #error "Unknown or unsupported OS."
2062
2063 #endif
2064
2065 return r > 0 ? r : 2; /* guess value of 2 if OS told us 0 */
2066
2067} // __kmp_get_xproc
2068
Jim Cownie181b4bb2013-12-23 17:28:57 +00002069int
2070__kmp_read_from_file( char const *path, char const *format, ... )
2071{
2072 int result;
2073 va_list args;
Jim Cownie5e8470a2013-09-27 10:38:44 +00002074
Jim Cownie181b4bb2013-12-23 17:28:57 +00002075 va_start(args, format);
2076 FILE *f = fopen(path, "rb");
2077 if ( f == NULL )
2078 return 0;
2079 result = vfscanf(f, format, args);
2080 fclose(f);
Jim Cownie5e8470a2013-09-27 10:38:44 +00002081
Jim Cownie5e8470a2013-09-27 10:38:44 +00002082 return result;
Jim Cownie181b4bb2013-12-23 17:28:57 +00002083}
Jim Cownie5e8470a2013-09-27 10:38:44 +00002084
2085void
2086__kmp_runtime_initialize( void )
2087{
2088 int status;
2089 pthread_mutexattr_t mutex_attr;
2090 pthread_condattr_t cond_attr;
2091
2092 if ( __kmp_init_runtime ) {
2093 return;
2094 }; // if
2095
2096 #if ( KMP_ARCH_X86 || KMP_ARCH_X86_64 )
2097 if ( ! __kmp_cpuinfo.initialized ) {
2098 __kmp_query_cpuid( &__kmp_cpuinfo );
2099 }; // if
2100 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
2101
Jim Cownie5e8470a2013-09-27 10:38:44 +00002102 __kmp_xproc = __kmp_get_xproc();
2103
2104 if ( sysconf( _SC_THREADS ) ) {
2105
2106 /* Query the maximum number of threads */
2107 __kmp_sys_max_nth = sysconf( _SC_THREAD_THREADS_MAX );
2108 if ( __kmp_sys_max_nth == -1 ) {
2109 /* Unlimited threads for NPTL */
2110 __kmp_sys_max_nth = INT_MAX;
2111 }
2112 else if ( __kmp_sys_max_nth <= 1 ) {
2113 /* Can't tell, just use PTHREAD_THREADS_MAX */
2114 __kmp_sys_max_nth = KMP_MAX_NTH;
2115 }
2116
2117 /* Query the minimum stack size */
2118 __kmp_sys_min_stksize = sysconf( _SC_THREAD_STACK_MIN );
2119 if ( __kmp_sys_min_stksize <= 1 ) {
2120 __kmp_sys_min_stksize = KMP_MIN_STKSIZE;
2121 }
2122 }
2123
2124 /* Set up minimum number of threads to switch to TLS gtid */
2125 __kmp_tls_gtid_min = KMP_TLS_GTID_MIN;
2126
Jim Cownie5e8470a2013-09-27 10:38:44 +00002127 #ifdef BUILD_TV
2128 {
2129 int rc = pthread_key_create( & __kmp_tv_key, 0 );
2130 KMP_CHECK_SYSFAIL( "pthread_key_create", rc );
2131 }
2132 #endif
2133
2134 status = pthread_key_create( &__kmp_gtid_threadprivate_key, __kmp_internal_end_dest );
2135 KMP_CHECK_SYSFAIL( "pthread_key_create", status );
2136 status = pthread_mutexattr_init( & mutex_attr );
2137 KMP_CHECK_SYSFAIL( "pthread_mutexattr_init", status );
2138 status = pthread_mutex_init( & __kmp_wait_mx.m_mutex, & mutex_attr );
2139 KMP_CHECK_SYSFAIL( "pthread_mutex_init", status );
2140 status = pthread_condattr_init( & cond_attr );
2141 KMP_CHECK_SYSFAIL( "pthread_condattr_init", status );
2142 status = pthread_cond_init( & __kmp_wait_cv.c_cond, & cond_attr );
2143 KMP_CHECK_SYSFAIL( "pthread_cond_init", status );
2144#if USE_ITT_BUILD
2145 __kmp_itt_initialize();
2146#endif /* USE_ITT_BUILD */
2147
2148 __kmp_init_runtime = TRUE;
2149}
2150
2151void
2152__kmp_runtime_destroy( void )
2153{
2154 int status;
2155
2156 if ( ! __kmp_init_runtime ) {
2157 return; // Nothing to do.
2158 };
2159
2160#if USE_ITT_BUILD
2161 __kmp_itt_destroy();
2162#endif /* USE_ITT_BUILD */
2163
2164 status = pthread_key_delete( __kmp_gtid_threadprivate_key );
2165 KMP_CHECK_SYSFAIL( "pthread_key_delete", status );
2166 #ifdef BUILD_TV
2167 status = pthread_key_delete( __kmp_tv_key );
2168 KMP_CHECK_SYSFAIL( "pthread_key_delete", status );
2169 #endif
2170
2171 status = pthread_mutex_destroy( & __kmp_wait_mx.m_mutex );
2172 if ( status != 0 && status != EBUSY ) {
2173 KMP_SYSFAIL( "pthread_mutex_destroy", status );
2174 }
2175 status = pthread_cond_destroy( & __kmp_wait_cv.c_cond );
2176 if ( status != 0 && status != EBUSY ) {
2177 KMP_SYSFAIL( "pthread_cond_destroy", status );
2178 }
Alp Toker763b9392014-02-28 09:42:41 +00002179 #if KMP_AFFINITY_SUPPORTED
Jim Cownie5e8470a2013-09-27 10:38:44 +00002180 __kmp_affinity_uninitialize();
Jim Cownie5e8470a2013-09-27 10:38:44 +00002181 #endif
2182
2183 __kmp_init_runtime = FALSE;
2184}
2185
2186
2187/* Put the thread to sleep for a time period */
2188/* NOTE: not currently used anywhere */
2189void
2190__kmp_thread_sleep( int millis )
2191{
2192 sleep( ( millis + 500 ) / 1000 );
2193}
2194
2195/* Calculate the elapsed wall clock time for the user */
2196void
2197__kmp_elapsed( double *t )
2198{
2199 int status;
2200# ifdef FIX_SGI_CLOCK
2201 struct timespec ts;
2202
2203 status = clock_gettime( CLOCK_PROCESS_CPUTIME_ID, &ts );
2204 KMP_CHECK_SYSFAIL_ERRNO( "clock_gettime", status );
Jonathan Peyton1e7a1dd2015-06-04 17:29:13 +00002205 *t = (double) ts.tv_nsec * (1.0 / (double) KMP_NSEC_PER_SEC) +
Jim Cownie5e8470a2013-09-27 10:38:44 +00002206 (double) ts.tv_sec;
2207# else
2208 struct timeval tv;
2209
2210 status = gettimeofday( & tv, NULL );
2211 KMP_CHECK_SYSFAIL_ERRNO( "gettimeofday", status );
Jonathan Peyton1e7a1dd2015-06-04 17:29:13 +00002212 *t = (double) tv.tv_usec * (1.0 / (double) KMP_USEC_PER_SEC) +
Jim Cownie5e8470a2013-09-27 10:38:44 +00002213 (double) tv.tv_sec;
2214# endif
2215}
2216
2217/* Calculate the elapsed wall clock tick for the user */
2218void
2219__kmp_elapsed_tick( double *t )
2220{
2221 *t = 1 / (double) CLOCKS_PER_SEC;
2222}
2223
Jonathan Peyton377aa402016-04-14 16:00:37 +00002224/* Return the current time stamp in nsec */
2225kmp_uint64
2226__kmp_now_nsec()
2227{
2228 struct timeval t;
2229 gettimeofday(&t, NULL);
2230 return KMP_NSEC_PER_SEC*t.tv_sec + 1000*t.tv_usec;
2231}
2232
Jonathan Peytonb66d1aa2016-09-27 17:11:17 +00002233#if KMP_ARCH_X86 || KMP_ARCH_X86_64
2234/* Measure clock tick per nanosecond */
2235void
2236__kmp_initialize_system_tick()
2237{
2238 kmp_uint64 delay = 100000; // 50~100 usec on most machines.
2239 kmp_uint64 nsec = __kmp_now_nsec();
2240 kmp_uint64 goal = __kmp_hardware_timestamp() + delay;
2241 kmp_uint64 now;
2242 while ((now = __kmp_hardware_timestamp()) < goal);
2243 __kmp_ticks_per_nsec = 1.0 * (delay + (now - goal)) / (__kmp_now_nsec() - nsec);
2244}
2245#endif
2246
Jim Cownie5e8470a2013-09-27 10:38:44 +00002247/*
2248 Determine whether the given address is mapped into the current address space.
2249*/
2250
2251int
2252__kmp_is_address_mapped( void * addr ) {
2253
2254 int found = 0;
2255 int rc;
2256
Joerg Sonnenberger7649cd42015-09-21 20:29:12 +00002257 #if KMP_OS_LINUX || KMP_OS_FREEBSD
Jim Cownie5e8470a2013-09-27 10:38:44 +00002258
2259 /*
2260 On Linux* OS, read the /proc/<pid>/maps pseudo-file to get all the address ranges mapped
2261 into the address space.
2262 */
2263
2264 char * name = __kmp_str_format( "/proc/%d/maps", getpid() );
2265 FILE * file = NULL;
2266
2267 file = fopen( name, "r" );
2268 KMP_ASSERT( file != NULL );
2269
2270 for ( ; ; ) {
2271
2272 void * beginning = NULL;
2273 void * ending = NULL;
2274 char perms[ 5 ];
2275
2276 rc = fscanf( file, "%p-%p %4s %*[^\n]\n", & beginning, & ending, perms );
2277 if ( rc == EOF ) {
2278 break;
2279 }; // if
Andrey Churbanov74bf17b2015-04-02 13:27:08 +00002280 KMP_ASSERT( rc == 3 && KMP_STRLEN( perms ) == 4 ); // Make sure all fields are read.
Jim Cownie5e8470a2013-09-27 10:38:44 +00002281
2282 // Ending address is not included in the region, but beginning is.
2283 if ( ( addr >= beginning ) && ( addr < ending ) ) {
2284 perms[ 2 ] = 0; // 3th and 4th character does not matter.
2285 if ( strcmp( perms, "rw" ) == 0 ) {
2286 // Memory we are looking for should be readable and writable.
2287 found = 1;
2288 }; // if
2289 break;
2290 }; // if
2291
2292 }; // forever
2293
2294 // Free resources.
2295 fclose( file );
2296 KMP_INTERNAL_FREE( name );
2297
2298 #elif KMP_OS_DARWIN
2299
2300 /*
2301 On OS X*, /proc pseudo filesystem is not available. Try to read memory using vm
2302 interface.
2303 */
2304
2305 int buffer;
2306 vm_size_t count;
2307 rc =
2308 vm_read_overwrite(
2309 mach_task_self(), // Task to read memory of.
2310 (vm_address_t)( addr ), // Address to read from.
2311 1, // Number of bytes to be read.
2312 (vm_address_t)( & buffer ), // Address of buffer to save read bytes in.
2313 & count // Address of var to save number of read bytes in.
2314 );
2315 if ( rc == 0 ) {
2316 // Memory successfully read.
2317 found = 1;
2318 }; // if
2319
Joerg Sonnenberger1564f3c2015-09-21 20:02:45 +00002320 #elif KMP_OS_FREEBSD || KMP_OS_NETBSD
Alp Toker763b9392014-02-28 09:42:41 +00002321
Joerg Sonnenberger1564f3c2015-09-21 20:02:45 +00002322 // FIXME(FreeBSD, NetBSD): Implement this
Alp Toker763b9392014-02-28 09:42:41 +00002323 found = 1;
2324
Jim Cownie5e8470a2013-09-27 10:38:44 +00002325 #else
2326
2327 #error "Unknown or unsupported OS"
2328
2329 #endif
2330
2331 return found;
2332
2333} // __kmp_is_address_mapped
2334
2335#ifdef USE_LOAD_BALANCE
2336
2337
2338# if KMP_OS_DARWIN
2339
2340// The function returns the rounded value of the system load average
2341// during given time interval which depends on the value of
2342// __kmp_load_balance_interval variable (default is 60 sec, other values
2343// may be 300 sec or 900 sec).
2344// It returns -1 in case of error.
2345int
2346__kmp_get_load_balance( int max )
2347{
2348 double averages[3];
2349 int ret_avg = 0;
2350
2351 int res = getloadavg( averages, 3 );
2352
2353 //Check __kmp_load_balance_interval to determine which of averages to use.
2354 // getloadavg() may return the number of samples less than requested that is
2355 // less than 3.
2356 if ( __kmp_load_balance_interval < 180 && ( res >= 1 ) ) {
2357 ret_avg = averages[0];// 1 min
2358 } else if ( ( __kmp_load_balance_interval >= 180
2359 && __kmp_load_balance_interval < 600 ) && ( res >= 2 ) ) {
2360 ret_avg = averages[1];// 5 min
2361 } else if ( ( __kmp_load_balance_interval >= 600 ) && ( res == 3 ) ) {
2362 ret_avg = averages[2];// 15 min
Alp Toker8f2d3f02014-02-24 10:40:15 +00002363 } else {// Error occurred
Jim Cownie5e8470a2013-09-27 10:38:44 +00002364 return -1;
2365 }
2366
2367 return ret_avg;
2368}
2369
2370# else // Linux* OS
2371
2372// The fuction returns number of running (not sleeping) threads, or -1 in case of error.
2373// Error could be reported if Linux* OS kernel too old (without "/proc" support).
2374// Counting running threads stops if max running threads encountered.
2375int
2376__kmp_get_load_balance( int max )
2377{
2378 static int permanent_error = 0;
2379
2380 static int glb_running_threads = 0; /* Saved count of the running threads for the thread balance algortihm */
2381 static double glb_call_time = 0; /* Thread balance algorithm call time */
2382
2383 int running_threads = 0; // Number of running threads in the system.
2384
2385 DIR * proc_dir = NULL; // Handle of "/proc/" directory.
2386 struct dirent * proc_entry = NULL;
2387
2388 kmp_str_buf_t task_path; // "/proc/<pid>/task/<tid>/" path.
2389 DIR * task_dir = NULL; // Handle of "/proc/<pid>/task/<tid>/" directory.
2390 struct dirent * task_entry = NULL;
2391 int task_path_fixed_len;
2392
2393 kmp_str_buf_t stat_path; // "/proc/<pid>/task/<tid>/stat" path.
2394 int stat_file = -1;
2395 int stat_path_fixed_len;
2396
2397 int total_processes = 0; // Total number of processes in system.
2398 int total_threads = 0; // Total number of threads in system.
2399
2400 double call_time = 0.0;
2401
2402 __kmp_str_buf_init( & task_path );
2403 __kmp_str_buf_init( & stat_path );
2404
2405 __kmp_elapsed( & call_time );
2406
2407 if ( glb_call_time &&
2408 ( call_time - glb_call_time < __kmp_load_balance_interval ) ) {
2409 running_threads = glb_running_threads;
2410 goto finish;
2411 }
2412
2413 glb_call_time = call_time;
2414
2415 // Do not spend time on scanning "/proc/" if we have a permanent error.
2416 if ( permanent_error ) {
2417 running_threads = -1;
2418 goto finish;
2419 }; // if
2420
2421 if ( max <= 0 ) {
2422 max = INT_MAX;
2423 }; // if
2424
2425 // Open "/proc/" directory.
2426 proc_dir = opendir( "/proc" );
2427 if ( proc_dir == NULL ) {
2428 // Cannot open "/prroc/". Probably the kernel does not support it. Return an error now and
2429 // in subsequent calls.
2430 running_threads = -1;
2431 permanent_error = 1;
2432 goto finish;
2433 }; // if
2434
2435 // Initialize fixed part of task_path. This part will not change.
2436 __kmp_str_buf_cat( & task_path, "/proc/", 6 );
2437 task_path_fixed_len = task_path.used; // Remember number of used characters.
2438
2439 proc_entry = readdir( proc_dir );
2440 while ( proc_entry != NULL ) {
2441 // Proc entry is a directory and name starts with a digit. Assume it is a process'
2442 // directory.
2443 if ( proc_entry->d_type == DT_DIR && isdigit( proc_entry->d_name[ 0 ] ) ) {
2444
2445 ++ total_processes;
2446 // Make sure init process is the very first in "/proc", so we can replace
2447 // strcmp( proc_entry->d_name, "1" ) == 0 with simpler total_processes == 1.
2448 // We are going to check that total_processes == 1 => d_name == "1" is true (where
2449 // "=>" is implication). Since C++ does not have => operator, let us replace it with its
2450 // equivalent: a => b == ! a || b.
2451 KMP_DEBUG_ASSERT( total_processes != 1 || strcmp( proc_entry->d_name, "1" ) == 0 );
2452
2453 // Construct task_path.
2454 task_path.used = task_path_fixed_len; // Reset task_path to "/proc/".
Andrey Churbanov74bf17b2015-04-02 13:27:08 +00002455 __kmp_str_buf_cat( & task_path, proc_entry->d_name, KMP_STRLEN( proc_entry->d_name ) );
Jim Cownie5e8470a2013-09-27 10:38:44 +00002456 __kmp_str_buf_cat( & task_path, "/task", 5 );
2457
2458 task_dir = opendir( task_path.str );
2459 if ( task_dir == NULL ) {
2460 // Process can finish between reading "/proc/" directory entry and opening process'
2461 // "task/" directory. So, in general case we should not complain, but have to skip
2462 // this process and read the next one.
2463 // But on systems with no "task/" support we will spend lot of time to scan "/proc/"
2464 // tree again and again without any benefit. "init" process (its pid is 1) should
2465 // exist always, so, if we cannot open "/proc/1/task/" directory, it means "task/"
2466 // is not supported by kernel. Report an error now and in the future.
2467 if ( strcmp( proc_entry->d_name, "1" ) == 0 ) {
2468 running_threads = -1;
2469 permanent_error = 1;
2470 goto finish;
2471 }; // if
2472 } else {
2473 // Construct fixed part of stat file path.
2474 __kmp_str_buf_clear( & stat_path );
2475 __kmp_str_buf_cat( & stat_path, task_path.str, task_path.used );
2476 __kmp_str_buf_cat( & stat_path, "/", 1 );
2477 stat_path_fixed_len = stat_path.used;
2478
2479 task_entry = readdir( task_dir );
2480 while ( task_entry != NULL ) {
2481 // It is a directory and name starts with a digit.
2482 if ( proc_entry->d_type == DT_DIR && isdigit( task_entry->d_name[ 0 ] ) ) {
2483
2484 ++ total_threads;
2485
2486 // Consruct complete stat file path. Easiest way would be:
2487 // __kmp_str_buf_print( & stat_path, "%s/%s/stat", task_path.str, task_entry->d_name );
2488 // but seriae of __kmp_str_buf_cat works a bit faster.
2489 stat_path.used = stat_path_fixed_len; // Reset stat path to its fixed part.
Andrey Churbanov74bf17b2015-04-02 13:27:08 +00002490 __kmp_str_buf_cat( & stat_path, task_entry->d_name, KMP_STRLEN( task_entry->d_name ) );
Jim Cownie5e8470a2013-09-27 10:38:44 +00002491 __kmp_str_buf_cat( & stat_path, "/stat", 5 );
2492
2493 // Note: Low-level API (open/read/close) is used. High-level API
2494 // (fopen/fclose) works ~ 30 % slower.
2495 stat_file = open( stat_path.str, O_RDONLY );
2496 if ( stat_file == -1 ) {
2497 // We cannot report an error because task (thread) can terminate just
2498 // before reading this file.
2499 } else {
2500 /*
2501 Content of "stat" file looks like:
2502
2503 24285 (program) S ...
2504
2505 It is a single line (if program name does not include fanny
2506 symbols). First number is a thread id, then name of executable file
2507 name in paretheses, then state of the thread. We need just thread
2508 state.
2509
2510 Good news: Length of program name is 15 characters max. Longer
2511 names are truncated.
2512
2513 Thus, we need rather short buffer: 15 chars for program name +
2514 2 parenthesis, + 3 spaces + ~7 digits of pid = 37.
2515
2516 Bad news: Program name may contain special symbols like space,
2517 closing parenthesis, or even new line. This makes parsing "stat"
2518 file not 100 % reliable. In case of fanny program names parsing
2519 may fail (report incorrect thread state).
2520
2521 Parsing "status" file looks more promissing (due to different
2522 file structure and escaping special symbols) but reading and
2523 parsing of "status" file works slower.
2524
2525 -- ln
2526 */
2527 char buffer[ 65 ];
2528 int len;
2529 len = read( stat_file, buffer, sizeof( buffer ) - 1 );
2530 if ( len >= 0 ) {
2531 buffer[ len ] = 0;
2532 // Using scanf:
2533 // sscanf( buffer, "%*d (%*s) %c ", & state );
2534 // looks very nice, but searching for a closing parenthesis works a
2535 // bit faster.
2536 char * close_parent = strstr( buffer, ") " );
2537 if ( close_parent != NULL ) {
2538 char state = * ( close_parent + 2 );
2539 if ( state == 'R' ) {
2540 ++ running_threads;
2541 if ( running_threads >= max ) {
2542 goto finish;
2543 }; // if
2544 }; // if
2545 }; // if
2546 }; // if
2547 close( stat_file );
2548 stat_file = -1;
2549 }; // if
2550 }; // if
2551 task_entry = readdir( task_dir );
2552 }; // while
2553 closedir( task_dir );
2554 task_dir = NULL;
2555 }; // if
2556 }; // if
2557 proc_entry = readdir( proc_dir );
2558 }; // while
2559
2560 //
2561 // There _might_ be a timing hole where the thread executing this
2562 // code get skipped in the load balance, and running_threads is 0.
2563 // Assert in the debug builds only!!!
2564 //
2565 KMP_DEBUG_ASSERT( running_threads > 0 );
2566 if ( running_threads <= 0 ) {
2567 running_threads = 1;
2568 }
2569
2570 finish: // Clean up and exit.
2571 if ( proc_dir != NULL ) {
2572 closedir( proc_dir );
2573 }; // if
2574 __kmp_str_buf_free( & task_path );
2575 if ( task_dir != NULL ) {
2576 closedir( task_dir );
2577 }; // if
2578 __kmp_str_buf_free( & stat_path );
2579 if ( stat_file != -1 ) {
2580 close( stat_file );
2581 }; // if
2582
2583 glb_running_threads = running_threads;
2584
2585 return running_threads;
2586
2587} // __kmp_get_load_balance
2588
2589# endif // KMP_OS_DARWIN
2590
2591#endif // USE_LOAD_BALANCE
2592
Hal Finkel91e19a32016-05-26 04:48:14 +00002593#if !(KMP_ARCH_X86 || KMP_ARCH_X86_64 || KMP_MIC || (KMP_OS_LINUX && KMP_ARCH_AARCH64) || KMP_ARCH_PPC64)
Jim Cownie3051f972014-08-07 10:12:54 +00002594
2595// we really only need the case with 1 argument, because CLANG always build
2596// a struct of pointers to shared variables referenced in the outlined function
2597int
2598__kmp_invoke_microtask( microtask_t pkfn,
2599 int gtid, int tid,
Jonathan Peyton61118492016-05-20 19:03:38 +00002600 int argc, void *p_argv[]
Jonathan Peyton122dd762015-07-13 18:55:45 +00002601#if OMPT_SUPPORT
2602 , void **exit_frame_ptr
2603#endif
Jonathan Peyton61118492016-05-20 19:03:38 +00002604)
Jonathan Peyton122dd762015-07-13 18:55:45 +00002605{
2606#if OMPT_SUPPORT
2607 *exit_frame_ptr = __builtin_frame_address(0);
2608#endif
2609
Jim Cownie3051f972014-08-07 10:12:54 +00002610 switch (argc) {
2611 default:
2612 fprintf(stderr, "Too many args to microtask: %d!\n", argc);
2613 fflush(stderr);
2614 exit(-1);
2615 case 0:
2616 (*pkfn)(&gtid, &tid);
2617 break;
2618 case 1:
2619 (*pkfn)(&gtid, &tid, p_argv[0]);
2620 break;
2621 case 2:
2622 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1]);
2623 break;
2624 case 3:
2625 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2]);
2626 break;
2627 case 4:
2628 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3]);
2629 break;
2630 case 5:
2631 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4]);
2632 break;
2633 case 6:
2634 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2635 p_argv[5]);
2636 break;
2637 case 7:
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]);
2640 break;
2641 case 8:
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]);
2644 break;
2645 case 9:
2646 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2647 p_argv[5], p_argv[6], p_argv[7], p_argv[8]);
2648 break;
2649 case 10:
2650 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2651 p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9]);
2652 break;
2653 case 11:
2654 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2655 p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9], p_argv[10]);
2656 break;
2657 case 12:
2658 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2659 p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9], p_argv[10],
2660 p_argv[11]);
2661 break;
2662 case 13:
2663 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2664 p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9], p_argv[10],
2665 p_argv[11], p_argv[12]);
2666 break;
2667 case 14:
2668 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2669 p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9], p_argv[10],
2670 p_argv[11], p_argv[12], p_argv[13]);
2671 break;
2672 case 15:
2673 (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
2674 p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9], p_argv[10],
2675 p_argv[11], p_argv[12], p_argv[13], p_argv[14]);
2676 break;
2677 }
2678
Jonathan Peyton122dd762015-07-13 18:55:45 +00002679#if OMPT_SUPPORT
2680 *exit_frame_ptr = 0;
2681#endif
2682
Jim Cownie3051f972014-08-07 10:12:54 +00002683 return 1;
2684}
2685
2686#endif
Jim Cownie181b4bb2013-12-23 17:28:57 +00002687
Jim Cownie5e8470a2013-09-27 10:38:44 +00002688// end of file //
2689