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