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