Intel® OpenMP* Runtime Library
 All Classes Functions Variables Typedefs Enumerations Enumerator Modules Pages
z_Windows_NT_util.c
1 /*
2  * z_Windows_NT_util.c -- platform specific routines.
3  */
4 
5 /* <copyright>
6  Copyright (c) 1997-2015 Intel Corporation. All Rights Reserved.
7 
8  Redistribution and use in source and binary forms, with or without
9  modification, are permitted provided that the following conditions
10  are met:
11 
12  * Redistributions of source code must retain the above copyright
13  notice, this list of conditions and the following disclaimer.
14  * Redistributions in binary form must reproduce the above copyright
15  notice, this list of conditions and the following disclaimer in the
16  documentation and/or other materials provided with the distribution.
17  * Neither the name of Intel Corporation nor the names of its
18  contributors may be used to endorse or promote products derived
19  from this software without specific prior written permission.
20 
21  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 
33 </copyright> */
34 
35 #include "kmp.h"
36 #include "kmp_itt.h"
37 #include "kmp_i18n.h"
38 #include "kmp_io.h"
39 #include "kmp_wait_release.h"
40 
41 
42 
43 /* ----------------------------------------------------------------------------------- */
44 /* ----------------------------------------------------------------------------------- */
45 
46 /* This code is related to NtQuerySystemInformation() function. This function
47  is used in the Load balance algorithm for OMP_DYNAMIC=true to find the
48  number of running threads in the system. */
49 
50 #include <ntstatus.h>
51 #include <ntsecapi.h> // UNICODE_STRING
52 
53 enum SYSTEM_INFORMATION_CLASS {
54  SystemProcessInformation = 5
55 }; // SYSTEM_INFORMATION_CLASS
56 
57 struct CLIENT_ID {
58  HANDLE UniqueProcess;
59  HANDLE UniqueThread;
60 }; // struct CLIENT_ID
61 
62 enum THREAD_STATE {
63  StateInitialized,
64  StateReady,
65  StateRunning,
66  StateStandby,
67  StateTerminated,
68  StateWait,
69  StateTransition,
70  StateUnknown
71 }; // enum THREAD_STATE
72 
73 struct VM_COUNTERS {
74  SIZE_T PeakVirtualSize;
75  SIZE_T VirtualSize;
76  ULONG PageFaultCount;
77  SIZE_T PeakWorkingSetSize;
78  SIZE_T WorkingSetSize;
79  SIZE_T QuotaPeakPagedPoolUsage;
80  SIZE_T QuotaPagedPoolUsage;
81  SIZE_T QuotaPeakNonPagedPoolUsage;
82  SIZE_T QuotaNonPagedPoolUsage;
83  SIZE_T PagefileUsage;
84  SIZE_T PeakPagefileUsage;
85  SIZE_T PrivatePageCount;
86 }; // struct VM_COUNTERS
87 
88 struct SYSTEM_THREAD {
89  LARGE_INTEGER KernelTime;
90  LARGE_INTEGER UserTime;
91  LARGE_INTEGER CreateTime;
92  ULONG WaitTime;
93  LPVOID StartAddress;
94  CLIENT_ID ClientId;
95  DWORD Priority;
96  LONG BasePriority;
97  ULONG ContextSwitchCount;
98  THREAD_STATE State;
99  ULONG WaitReason;
100 }; // SYSTEM_THREAD
101 
102 KMP_BUILD_ASSERT( offsetof( SYSTEM_THREAD, KernelTime ) == 0 );
103 #if KMP_ARCH_X86
104  KMP_BUILD_ASSERT( offsetof( SYSTEM_THREAD, StartAddress ) == 28 );
105  KMP_BUILD_ASSERT( offsetof( SYSTEM_THREAD, State ) == 52 );
106 #else
107  KMP_BUILD_ASSERT( offsetof( SYSTEM_THREAD, StartAddress ) == 32 );
108  KMP_BUILD_ASSERT( offsetof( SYSTEM_THREAD, State ) == 68 );
109 #endif
110 
111 struct SYSTEM_PROCESS_INFORMATION {
112  ULONG NextEntryOffset;
113  ULONG NumberOfThreads;
114  LARGE_INTEGER Reserved[ 3 ];
115  LARGE_INTEGER CreateTime;
116  LARGE_INTEGER UserTime;
117  LARGE_INTEGER KernelTime;
118  UNICODE_STRING ImageName;
119  DWORD BasePriority;
120  HANDLE ProcessId;
121  HANDLE ParentProcessId;
122  ULONG HandleCount;
123  ULONG Reserved2[ 2 ];
124  VM_COUNTERS VMCounters;
125  IO_COUNTERS IOCounters;
126  SYSTEM_THREAD Threads[ 1 ];
127 }; // SYSTEM_PROCESS_INFORMATION
128 typedef SYSTEM_PROCESS_INFORMATION * PSYSTEM_PROCESS_INFORMATION;
129 
130 KMP_BUILD_ASSERT( offsetof( SYSTEM_PROCESS_INFORMATION, NextEntryOffset ) == 0 );
131 KMP_BUILD_ASSERT( offsetof( SYSTEM_PROCESS_INFORMATION, CreateTime ) == 32 );
132 KMP_BUILD_ASSERT( offsetof( SYSTEM_PROCESS_INFORMATION, ImageName ) == 56 );
133 #if KMP_ARCH_X86
134  KMP_BUILD_ASSERT( offsetof( SYSTEM_PROCESS_INFORMATION, ProcessId ) == 68 );
135  KMP_BUILD_ASSERT( offsetof( SYSTEM_PROCESS_INFORMATION, HandleCount ) == 76 );
136  KMP_BUILD_ASSERT( offsetof( SYSTEM_PROCESS_INFORMATION, VMCounters ) == 88 );
137  KMP_BUILD_ASSERT( offsetof( SYSTEM_PROCESS_INFORMATION, IOCounters ) == 136 );
138  KMP_BUILD_ASSERT( offsetof( SYSTEM_PROCESS_INFORMATION, Threads ) == 184 );
139 #else
140  KMP_BUILD_ASSERT( offsetof( SYSTEM_PROCESS_INFORMATION, ProcessId ) == 80 );
141  KMP_BUILD_ASSERT( offsetof( SYSTEM_PROCESS_INFORMATION, HandleCount ) == 96 );
142  KMP_BUILD_ASSERT( offsetof( SYSTEM_PROCESS_INFORMATION, VMCounters ) == 112 );
143  KMP_BUILD_ASSERT( offsetof( SYSTEM_PROCESS_INFORMATION, IOCounters ) == 208 );
144  KMP_BUILD_ASSERT( offsetof( SYSTEM_PROCESS_INFORMATION, Threads ) == 256 );
145 #endif
146 
147 typedef NTSTATUS (NTAPI *NtQuerySystemInformation_t)( SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG );
148 NtQuerySystemInformation_t NtQuerySystemInformation = NULL;
149 
150 HMODULE ntdll = NULL;
151 
152 /* End of NtQuerySystemInformation()-related code */
153 
154 #if KMP_GROUP_AFFINITY
155 static HMODULE kernel32 = NULL;
156 #endif /* KMP_GROUP_AFFINITY */
157 
158 /* ----------------------------------------------------------------------------------- */
159 /* ----------------------------------------------------------------------------------- */
160 
161 #if KMP_HANDLE_SIGNALS
162  typedef void (* sig_func_t )( int );
163  static sig_func_t __kmp_sighldrs[ NSIG ];
164  static int __kmp_siginstalled[ NSIG ];
165 #endif
166 
167 static HANDLE __kmp_monitor_ev;
168 static kmp_int64 __kmp_win32_time;
169 double __kmp_win32_tick;
170 
171 int __kmp_init_runtime = FALSE;
172 CRITICAL_SECTION __kmp_win32_section;
173 
174 void
175 __kmp_win32_mutex_init( kmp_win32_mutex_t *mx )
176 {
177  InitializeCriticalSection( & mx->cs );
178 #if USE_ITT_BUILD
179  __kmp_itt_system_object_created( & mx->cs, "Critical Section" );
180 #endif /* USE_ITT_BUILD */
181 }
182 
183 void
184 __kmp_win32_mutex_destroy( kmp_win32_mutex_t *mx )
185 {
186  DeleteCriticalSection( & mx->cs );
187 }
188 
189 void
190 __kmp_win32_mutex_lock( kmp_win32_mutex_t *mx )
191 {
192  EnterCriticalSection( & mx->cs );
193 }
194 
195 void
196 __kmp_win32_mutex_unlock( kmp_win32_mutex_t *mx )
197 {
198  LeaveCriticalSection( & mx->cs );
199 }
200 
201 void
202 __kmp_win32_cond_init( kmp_win32_cond_t *cv )
203 {
204  cv->waiters_count_ = 0;
205  cv->wait_generation_count_ = 0;
206  cv->release_count_ = 0;
207 
208  /* Initialize the critical section */
209  __kmp_win32_mutex_init( & cv->waiters_count_lock_ );
210 
211  /* Create a manual-reset event. */
212  cv->event_ = CreateEvent( NULL, // no security
213  TRUE, // manual-reset
214  FALSE, // non-signaled initially
215  NULL ); // unnamed
216 #if USE_ITT_BUILD
217  __kmp_itt_system_object_created( cv->event_, "Event" );
218 #endif /* USE_ITT_BUILD */
219 }
220 
221 void
222 __kmp_win32_cond_destroy( kmp_win32_cond_t *cv )
223 {
224  __kmp_win32_mutex_destroy( & cv->waiters_count_lock_ );
225  __kmp_free_handle( cv->event_ );
226  memset( cv, '\0', sizeof( *cv ) );
227 }
228 
229 /* TODO associate cv with a team instead of a thread so as to optimize
230  * the case where we wake up a whole team */
231 
232 void
233 __kmp_win32_cond_wait( kmp_win32_cond_t *cv, kmp_win32_mutex_t *mx, kmp_info_t *th, int need_decrease_load )
234 {
235  int my_generation;
236  int last_waiter;
237 
238  /* Avoid race conditions */
239  __kmp_win32_mutex_lock( &cv->waiters_count_lock_ );
240 
241  /* Increment count of waiters */
242  cv->waiters_count_++;
243 
244  /* Store current generation in our activation record. */
245  my_generation = cv->wait_generation_count_;
246 
247  __kmp_win32_mutex_unlock( &cv->waiters_count_lock_ );
248  __kmp_win32_mutex_unlock( mx );
249 
250 
251  for (;;) {
252  int wait_done;
253 
254  /* Wait until the event is signaled */
255  WaitForSingleObject( cv->event_, INFINITE );
256 
257  __kmp_win32_mutex_lock( &cv->waiters_count_lock_ );
258 
259  /* Exit the loop when the <cv->event_> is signaled and
260  * there are still waiting threads from this <wait_generation>
261  * that haven't been released from this wait yet. */
262  wait_done = ( cv->release_count_ > 0 ) &&
263  ( cv->wait_generation_count_ != my_generation );
264 
265  __kmp_win32_mutex_unlock( &cv->waiters_count_lock_);
266 
267  /* there used to be a semicolon after the if statement,
268  * it looked like a bug, so i removed it */
269  if( wait_done )
270  break;
271  }
272 
273  __kmp_win32_mutex_lock( mx );
274  __kmp_win32_mutex_lock( &cv->waiters_count_lock_ );
275 
276  cv->waiters_count_--;
277  cv->release_count_--;
278 
279  last_waiter = ( cv->release_count_ == 0 );
280 
281  __kmp_win32_mutex_unlock( &cv->waiters_count_lock_ );
282 
283  if( last_waiter ) {
284  /* We're the last waiter to be notified, so reset the manual event. */
285  ResetEvent( cv->event_ );
286  }
287 }
288 
289 void
290 __kmp_win32_cond_broadcast( kmp_win32_cond_t *cv )
291 {
292  __kmp_win32_mutex_lock( &cv->waiters_count_lock_ );
293 
294  if( cv->waiters_count_ > 0 ) {
295  SetEvent( cv->event_ );
296  /* Release all the threads in this generation. */
297 
298  cv->release_count_ = cv->waiters_count_;
299 
300  /* Start a new generation. */
301  cv->wait_generation_count_++;
302  }
303 
304  __kmp_win32_mutex_unlock( &cv->waiters_count_lock_ );
305 }
306 
307 void
308 __kmp_win32_cond_signal( kmp_win32_cond_t *cv )
309 {
310  __kmp_win32_cond_broadcast( cv );
311 }
312 
313 /* ------------------------------------------------------------------------ */
314 /* ------------------------------------------------------------------------ */
315 
316 void
317 __kmp_enable( int new_state )
318 {
319  if (__kmp_init_runtime)
320  LeaveCriticalSection( & __kmp_win32_section );
321 }
322 
323 void
324 __kmp_disable( int *old_state )
325 {
326  *old_state = 0;
327 
328  if (__kmp_init_runtime)
329  EnterCriticalSection( & __kmp_win32_section );
330 }
331 
332 void
333 __kmp_suspend_initialize( void )
334 {
335  /* do nothing */
336 }
337 
338 static void
339 __kmp_suspend_initialize_thread( kmp_info_t *th )
340 {
341  if ( ! TCR_4( th->th.th_suspend_init ) ) {
342  /* this means we haven't initialized the suspension pthread objects for this thread
343  in this instance of the process */
344  __kmp_win32_cond_init( &th->th.th_suspend_cv );
345  __kmp_win32_mutex_init( &th->th.th_suspend_mx );
346  TCW_4( th->th.th_suspend_init, TRUE );
347  }
348 }
349 
350 void
351 __kmp_suspend_uninitialize_thread( kmp_info_t *th )
352 {
353  if ( TCR_4( th->th.th_suspend_init ) ) {
354  /* this means we have initialize the suspension pthread objects for this thread
355  in this instance of the process */
356  __kmp_win32_cond_destroy( & th->th.th_suspend_cv );
357  __kmp_win32_mutex_destroy( & th->th.th_suspend_mx );
358  TCW_4( th->th.th_suspend_init, FALSE );
359  }
360 }
361 
362 /* This routine puts the calling thread to sleep after setting the
363  * sleep bit for the indicated flag variable to true.
364  */
365 template <class C>
366 static inline void __kmp_suspend_template( int th_gtid, C *flag )
367 {
368  kmp_info_t *th = __kmp_threads[th_gtid];
369  int status;
370  typename C::flag_t old_spin;
371 
372  KF_TRACE( 30, ("__kmp_suspend_template: T#%d enter for flag's loc(%p)\n", th_gtid, flag->get() ) );
373 
374  __kmp_suspend_initialize_thread( th );
375  __kmp_win32_mutex_lock( &th->th.th_suspend_mx );
376 
377  KF_TRACE( 10, ( "__kmp_suspend_template: T#%d setting sleep bit for flag's loc(%p)\n",
378  th_gtid, flag->get() ) );
379 
380  /* TODO: shouldn't this use release semantics to ensure that __kmp_suspend_initialize_thread
381  gets called first?
382  */
383  old_spin = flag->set_sleeping();
384 
385  KF_TRACE( 5, ( "__kmp_suspend_template: T#%d set sleep bit for flag's loc(%p)==%d\n",
386  th_gtid, flag->get(), *(flag->get()) ) );
387 
388  if ( flag->done_check_val(old_spin) ) {
389  old_spin = flag->unset_sleeping();
390  KF_TRACE( 5, ( "__kmp_suspend_template: T#%d false alarm, reset sleep bit for flag's loc(%p)\n",
391  th_gtid, flag->get()) );
392  } else {
393 #ifdef DEBUG_SUSPEND
394  __kmp_suspend_count++;
395 #endif
396  /* Encapsulate in a loop as the documentation states that this may
397  * "with low probability" return when the condition variable has
398  * not been signaled or broadcast
399  */
400  int deactivated = FALSE;
401  TCW_PTR(th->th.th_sleep_loc, (void *)flag);
402  while ( flag->is_sleeping() ) {
403  KF_TRACE( 15, ("__kmp_suspend_template: T#%d about to perform kmp_win32_cond_wait()\n",
404  th_gtid ) );
405  // Mark the thread as no longer active (only in the first iteration of the loop).
406  if ( ! deactivated ) {
407  th->th.th_active = FALSE;
408  if ( th->th.th_active_in_pool ) {
409  th->th.th_active_in_pool = FALSE;
410  KMP_TEST_THEN_DEC32(
411  (kmp_int32 *) &__kmp_thread_pool_active_nth );
412  KMP_DEBUG_ASSERT( TCR_4(__kmp_thread_pool_active_nth) >= 0 );
413  }
414  deactivated = TRUE;
415 
416 
417  __kmp_win32_cond_wait( &th->th.th_suspend_cv, &th->th.th_suspend_mx, 0, 0 );
418  }
419  else {
420  __kmp_win32_cond_wait( &th->th.th_suspend_cv, &th->th.th_suspend_mx, 0, 0 );
421  }
422 
423 #ifdef KMP_DEBUG
424  if( flag->is_sleeping() ) {
425  KF_TRACE( 100, ("__kmp_suspend_template: T#%d spurious wakeup\n", th_gtid ));
426  }
427 #endif /* KMP_DEBUG */
428 
429  } // while
430 
431  // Mark the thread as active again (if it was previous marked as inactive)
432  if ( deactivated ) {
433  th->th.th_active = TRUE;
434  if ( TCR_4(th->th.th_in_pool) ) {
435  KMP_TEST_THEN_INC32(
436  (kmp_int32 *) &__kmp_thread_pool_active_nth );
437  th->th.th_active_in_pool = TRUE;
438  }
439  }
440  }
441 
442 
443  __kmp_win32_mutex_unlock( &th->th.th_suspend_mx );
444 
445  KF_TRACE( 30, ("__kmp_suspend_template: T#%d exit\n", th_gtid ) );
446 }
447 
448 void __kmp_suspend_32(int th_gtid, kmp_flag_32 *flag) {
449  __kmp_suspend_template(th_gtid, flag);
450 }
451 void __kmp_suspend_64(int th_gtid, kmp_flag_64 *flag) {
452  __kmp_suspend_template(th_gtid, flag);
453 }
454 void __kmp_suspend_oncore(int th_gtid, kmp_flag_oncore *flag) {
455  __kmp_suspend_template(th_gtid, flag);
456 }
457 
458 
459 /* This routine signals the thread specified by target_gtid to wake up
460  * after setting the sleep bit indicated by the flag argument to FALSE
461  */
462 template <class C>
463 static inline void __kmp_resume_template( int target_gtid, C *flag )
464 {
465  kmp_info_t *th = __kmp_threads[target_gtid];
466  int status;
467 
468 #ifdef KMP_DEBUG
469  int gtid = TCR_4(__kmp_init_gtid) ? __kmp_get_gtid() : -1;
470 #endif
471 
472  KF_TRACE( 30, ( "__kmp_resume_template: T#%d wants to wakeup T#%d enter\n", gtid, target_gtid ) );
473 
474  __kmp_suspend_initialize_thread( th );
475  __kmp_win32_mutex_lock( &th->th.th_suspend_mx );
476 
477  if (!flag) {
478  flag = (C *)th->th.th_sleep_loc;
479  }
480 
481  if (!flag) {
482  KF_TRACE( 5, ( "__kmp_resume_template: T#%d exiting, thread T#%d already awake: flag's loc(%p)\n",
483  gtid, target_gtid, NULL ) );
484  __kmp_win32_mutex_unlock( &th->th.th_suspend_mx );
485  return;
486  }
487  else {
488  typename C::flag_t old_spin = flag->unset_sleeping();
489  if ( !flag->is_sleeping_val(old_spin) ) {
490  KF_TRACE( 5, ( "__kmp_resume_template: T#%d exiting, thread T#%d already awake: flag's loc(%p): "
491  "%u => %u\n",
492  gtid, target_gtid, flag->get(), old_spin, *(flag->get()) ) );
493  __kmp_win32_mutex_unlock( &th->th.th_suspend_mx );
494  return;
495  }
496  }
497  TCW_PTR(th->th.th_sleep_loc, NULL);
498 
499  KF_TRACE( 5, ( "__kmp_resume_template: T#%d about to wakeup T#%d, reset sleep bit for flag's loc(%p)\n",
500  gtid, target_gtid, flag->get() ) );
501 
502 
503  __kmp_win32_cond_signal( &th->th.th_suspend_cv );
504  __kmp_win32_mutex_unlock( &th->th.th_suspend_mx );
505 
506  KF_TRACE( 30, ( "__kmp_resume_template: T#%d exiting after signaling wake up for T#%d\n",
507  gtid, target_gtid ) );
508 }
509 
510 void __kmp_resume_32(int target_gtid, kmp_flag_32 *flag) {
511  __kmp_resume_template(target_gtid, flag);
512 }
513 void __kmp_resume_64(int target_gtid, kmp_flag_64 *flag) {
514  __kmp_resume_template(target_gtid, flag);
515 }
516 void __kmp_resume_oncore(int target_gtid, kmp_flag_oncore *flag) {
517  __kmp_resume_template(target_gtid, flag);
518 }
519 
520 
521 /* ------------------------------------------------------------------------ */
522 /* ------------------------------------------------------------------------ */
523 
524 void
525 __kmp_yield( int cond )
526 {
527  if (cond)
528  Sleep(0);
529 }
530 
531 /* ------------------------------------------------------------------------ */
532 /* ------------------------------------------------------------------------ */
533 
534 void
535 __kmp_gtid_set_specific( int gtid )
536 {
537  KA_TRACE( 50, ("__kmp_gtid_set_specific: T#%d key:%d\n",
538  gtid, __kmp_gtid_threadprivate_key ));
539  KMP_ASSERT( __kmp_init_runtime );
540  if( ! TlsSetValue( __kmp_gtid_threadprivate_key, (LPVOID)(gtid+1)) )
541  KMP_FATAL( TLSSetValueFailed );
542 }
543 
544 int
545 __kmp_gtid_get_specific()
546 {
547  int gtid;
548  if( !__kmp_init_runtime ) {
549  KA_TRACE( 50, ("__kmp_get_specific: runtime shutdown, returning KMP_GTID_SHUTDOWN\n" ) );
550  return KMP_GTID_SHUTDOWN;
551  }
552  gtid = (int)(kmp_intptr_t)TlsGetValue( __kmp_gtid_threadprivate_key );
553  if ( gtid == 0 ) {
554  gtid = KMP_GTID_DNE;
555  }
556  else {
557  gtid--;
558  }
559  KA_TRACE( 50, ("__kmp_gtid_get_specific: key:%d gtid:%d\n",
560  __kmp_gtid_threadprivate_key, gtid ));
561  return gtid;
562 }
563 
564 /* ------------------------------------------------------------------------ */
565 /* ------------------------------------------------------------------------ */
566 
567 #if KMP_GROUP_AFFINITY
568 
569 //
570 // Only 1 DWORD in the mask should have any procs set.
571 // Return the appropriate index, or -1 for an invalid mask.
572 //
573 int
574 __kmp_get_proc_group( kmp_affin_mask_t const *mask )
575 {
576  int i;
577  int group = -1;
578  for (i = 0; i < __kmp_num_proc_groups; i++) {
579  if (mask[i] == 0) {
580  continue;
581  }
582  if (group >= 0) {
583  return -1;
584  }
585  group = i;
586  }
587  return group;
588 }
589 
590 #endif /* KMP_GROUP_AFFINITY */
591 
592 int
593 __kmp_set_system_affinity( kmp_affin_mask_t const *mask, int abort_on_error )
594 {
595 
596 #if KMP_GROUP_AFFINITY
597 
598  if (__kmp_num_proc_groups > 1) {
599  //
600  // Check for a valid mask.
601  //
602  GROUP_AFFINITY ga;
603  int group = __kmp_get_proc_group( mask );
604  if (group < 0) {
605  if (abort_on_error) {
606  KMP_FATAL(AffinityInvalidMask, "kmp_set_affinity");
607  }
608  return -1;
609  }
610 
611  //
612  // Transform the bit vector into a GROUP_AFFINITY struct
613  // and make the system call to set affinity.
614  //
615  ga.Group = group;
616  ga.Mask = mask[group];
617  ga.Reserved[0] = ga.Reserved[1] = ga.Reserved[2] = 0;
618 
619  KMP_DEBUG_ASSERT(__kmp_SetThreadGroupAffinity != NULL);
620  if (__kmp_SetThreadGroupAffinity(GetCurrentThread(), &ga, NULL) == 0) {
621  DWORD error = GetLastError();
622  if (abort_on_error) {
623  __kmp_msg(
624  kmp_ms_fatal,
625  KMP_MSG( CantSetThreadAffMask ),
626  KMP_ERR( error ),
627  __kmp_msg_null
628  );
629  }
630  return error;
631  }
632  }
633  else
634 
635 #endif /* KMP_GROUP_AFFINITY */
636 
637  {
638  if (!SetThreadAffinityMask( GetCurrentThread(), *mask )) {
639  DWORD error = GetLastError();
640  if (abort_on_error) {
641  __kmp_msg(
642  kmp_ms_fatal,
643  KMP_MSG( CantSetThreadAffMask ),
644  KMP_ERR( error ),
645  __kmp_msg_null
646  );
647  }
648  return error;
649  }
650  }
651  return 0;
652 }
653 
654 int
655 __kmp_get_system_affinity( kmp_affin_mask_t *mask, int abort_on_error )
656 {
657 
658 #if KMP_GROUP_AFFINITY
659 
660  if (__kmp_num_proc_groups > 1) {
661  KMP_CPU_ZERO(mask);
662  GROUP_AFFINITY ga;
663  KMP_DEBUG_ASSERT(__kmp_GetThreadGroupAffinity != NULL);
664 
665  if (__kmp_GetThreadGroupAffinity(GetCurrentThread(), &ga) == 0) {
666  DWORD error = GetLastError();
667  if (abort_on_error) {
668  __kmp_msg(
669  kmp_ms_fatal,
670  KMP_MSG(FunctionError, "GetThreadGroupAffinity()"),
671  KMP_ERR(error),
672  __kmp_msg_null
673  );
674  }
675  return error;
676  }
677 
678  if ((ga.Group < 0) || (ga.Group > __kmp_num_proc_groups)
679  || (ga.Mask == 0)) {
680  return -1;
681  }
682 
683  mask[ga.Group] = ga.Mask;
684  }
685  else
686 
687 #endif /* KMP_GROUP_AFFINITY */
688 
689  {
690  kmp_affin_mask_t newMask, sysMask, retval;
691 
692  if (!GetProcessAffinityMask(GetCurrentProcess(), &newMask, &sysMask)) {
693  DWORD error = GetLastError();
694  if (abort_on_error) {
695  __kmp_msg(
696  kmp_ms_fatal,
697  KMP_MSG(FunctionError, "GetProcessAffinityMask()"),
698  KMP_ERR(error),
699  __kmp_msg_null
700  );
701  }
702  return error;
703  }
704  retval = SetThreadAffinityMask(GetCurrentThread(), newMask);
705  if (! retval) {
706  DWORD error = GetLastError();
707  if (abort_on_error) {
708  __kmp_msg(
709  kmp_ms_fatal,
710  KMP_MSG(FunctionError, "SetThreadAffinityMask()"),
711  KMP_ERR(error),
712  __kmp_msg_null
713  );
714  }
715  return error;
716  }
717  newMask = SetThreadAffinityMask(GetCurrentThread(), retval);
718  if (! newMask) {
719  DWORD error = GetLastError();
720  if (abort_on_error) {
721  __kmp_msg(
722  kmp_ms_fatal,
723  KMP_MSG(FunctionError, "SetThreadAffinityMask()"),
724  KMP_ERR(error),
725  __kmp_msg_null
726  );
727  }
728  }
729  *mask = retval;
730  }
731  return 0;
732 }
733 
734 void
735 __kmp_affinity_bind_thread( int proc )
736 {
737 
738 #if KMP_GROUP_AFFINITY
739 
740  if (__kmp_num_proc_groups > 1) {
741  //
742  // Form the GROUP_AFFINITY struct directly, rather than filling
743  // out a bit vector and calling __kmp_set_system_affinity().
744  //
745  GROUP_AFFINITY ga;
746  KMP_DEBUG_ASSERT((proc >= 0) && (proc < (__kmp_num_proc_groups
747  * CHAR_BIT * sizeof(DWORD_PTR))));
748  ga.Group = proc / (CHAR_BIT * sizeof(DWORD_PTR));
749  ga.Mask = (unsigned long long)1 << (proc % (CHAR_BIT * sizeof(DWORD_PTR)));
750  ga.Reserved[0] = ga.Reserved[1] = ga.Reserved[2] = 0;
751 
752  KMP_DEBUG_ASSERT(__kmp_SetThreadGroupAffinity != NULL);
753  if (__kmp_SetThreadGroupAffinity(GetCurrentThread(), &ga, NULL) == 0) {
754  DWORD error = GetLastError();
755  if (__kmp_affinity_verbose) { // AC: continue silently if not verbose
756  __kmp_msg(
757  kmp_ms_warning,
758  KMP_MSG( CantSetThreadAffMask ),
759  KMP_ERR( error ),
760  __kmp_msg_null
761  );
762  }
763  }
764  }
765  else
766 
767 #endif /* KMP_GROUP_AFFINITY */
768 
769  {
770  kmp_affin_mask_t mask;
771  KMP_CPU_ZERO(&mask);
772  KMP_CPU_SET(proc, &mask);
773  __kmp_set_system_affinity(&mask, TRUE);
774  }
775 }
776 
777 void
778 __kmp_affinity_determine_capable( const char *env_var )
779 {
780  //
781  // All versions of Windows* OS (since Win '95) support SetThreadAffinityMask().
782  //
783 
784 #if KMP_GROUP_AFFINITY
785  KMP_AFFINITY_ENABLE(__kmp_num_proc_groups*sizeof(kmp_affin_mask_t));
786 #else
787  KMP_AFFINITY_ENABLE(sizeof(kmp_affin_mask_t));
788 #endif
789 
790  KA_TRACE( 10, (
791  "__kmp_affinity_determine_capable: "
792  "Windows* OS affinity interface functional (mask size = %" KMP_SIZE_T_SPEC ").\n",
793  __kmp_affin_mask_size
794  ) );
795 }
796 
797 double
798 __kmp_read_cpu_time( void )
799 {
800  FILETIME CreationTime, ExitTime, KernelTime, UserTime;
801  int status;
802  double cpu_time;
803 
804  cpu_time = 0;
805 
806  status = GetProcessTimes( GetCurrentProcess(), &CreationTime,
807  &ExitTime, &KernelTime, &UserTime );
808 
809  if (status) {
810  double sec = 0;
811 
812  sec += KernelTime.dwHighDateTime;
813  sec += UserTime.dwHighDateTime;
814 
815  /* Shift left by 32 bits */
816  sec *= (double) (1 << 16) * (double) (1 << 16);
817 
818  sec += KernelTime.dwLowDateTime;
819  sec += UserTime.dwLowDateTime;
820 
821  cpu_time += (sec * 100.0) / NSEC_PER_SEC;
822  }
823 
824  return cpu_time;
825 }
826 
827 int
828 __kmp_read_system_info( struct kmp_sys_info *info )
829 {
830  info->maxrss = 0; /* the maximum resident set size utilized (in kilobytes) */
831  info->minflt = 0; /* the number of page faults serviced without any I/O */
832  info->majflt = 0; /* the number of page faults serviced that required I/O */
833  info->nswap = 0; /* the number of times a process was "swapped" out of memory */
834  info->inblock = 0; /* the number of times the file system had to perform input */
835  info->oublock = 0; /* the number of times the file system had to perform output */
836  info->nvcsw = 0; /* the number of times a context switch was voluntarily */
837  info->nivcsw = 0; /* the number of times a context switch was forced */
838 
839  return 1;
840 }
841 
842 /* ------------------------------------------------------------------------ */
843 /* ------------------------------------------------------------------------ */
844 
845 
846 void
847 __kmp_runtime_initialize( void )
848 {
849  SYSTEM_INFO info;
850  kmp_str_buf_t path;
851  UINT path_size;
852 
853  if ( __kmp_init_runtime ) {
854  return;
855  };
856 
857 #if KMP_DYNAMIC_LIB
858  /* Pin dynamic library for the lifetime of application */
859  {
860  // First, turn off error message boxes
861  UINT err_mode = SetErrorMode (SEM_FAILCRITICALERRORS);
862  HMODULE h;
863  BOOL ret = GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
864  |GET_MODULE_HANDLE_EX_FLAG_PIN,
865  (LPCTSTR)&__kmp_serial_initialize, &h);
866  KMP_DEBUG_ASSERT2(h && ret, "OpenMP RTL cannot find itself loaded");
867  SetErrorMode (err_mode); // Restore error mode
868  KA_TRACE( 10, ("__kmp_runtime_initialize: dynamic library pinned\n") );
869  }
870 #endif
871 
872  InitializeCriticalSection( & __kmp_win32_section );
873 #if USE_ITT_BUILD
874  __kmp_itt_system_object_created( & __kmp_win32_section, "Critical Section" );
875 #endif /* USE_ITT_BUILD */
876  __kmp_initialize_system_tick();
877 
878  #if (KMP_ARCH_X86 || KMP_ARCH_X86_64)
879  if ( ! __kmp_cpuinfo.initialized ) {
880  __kmp_query_cpuid( & __kmp_cpuinfo );
881  }; // if
882  #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
883 
884  /* Set up minimum number of threads to switch to TLS gtid */
885  #if KMP_OS_WINDOWS && ! defined KMP_DYNAMIC_LIB
886  // Windows* OS, static library.
887  /*
888  New thread may use stack space previously used by another thread, currently terminated.
889  On Windows* OS, in case of static linking, we do not know the moment of thread termination,
890  and our structures (__kmp_threads and __kmp_root arrays) are still keep info about dead
891  threads. This leads to problem in __kmp_get_global_thread_id() function: it wrongly
892  finds gtid (by searching through stack addresses of all known threads) for unregistered
893  foreign tread.
894 
895  Setting __kmp_tls_gtid_min to 0 workarounds this problem: __kmp_get_global_thread_id()
896  does not search through stacks, but get gtid from TLS immediately.
897 
898  --ln
899  */
900  __kmp_tls_gtid_min = 0;
901  #else
902  __kmp_tls_gtid_min = KMP_TLS_GTID_MIN;
903  #endif
904 
905  /* for the static library */
906  if ( !__kmp_gtid_threadprivate_key ) {
907  __kmp_gtid_threadprivate_key = TlsAlloc();
908  if( __kmp_gtid_threadprivate_key == TLS_OUT_OF_INDEXES ) {
909  KMP_FATAL( TLSOutOfIndexes );
910  }
911  }
912 
913 
914  //
915  // Load ntdll.dll.
916  //
917  /*
918  Simple
919  GetModuleHandle( "ntdll.dl" )
920  is not suitable due to security issue (see
921  http://www.microsoft.com/technet/security/advisory/2269637.mspx). We have to specify full
922  path to the library.
923  */
924  __kmp_str_buf_init( & path );
925  path_size = GetSystemDirectory( path.str, path.size );
926  KMP_DEBUG_ASSERT( path_size > 0 );
927  if ( path_size >= path.size ) {
928  //
929  // Buffer is too short. Expand the buffer and try again.
930  //
931  __kmp_str_buf_reserve( & path, path_size );
932  path_size = GetSystemDirectory( path.str, path.size );
933  KMP_DEBUG_ASSERT( path_size > 0 );
934  }; // if
935  if ( path_size > 0 && path_size < path.size ) {
936  //
937  // Now we have system directory name in the buffer.
938  // Append backslash and name of dll to form full path,
939  //
940  path.used = path_size;
941  __kmp_str_buf_print( & path, "\\%s", "ntdll.dll" );
942 
943  //
944  // Now load ntdll using full path.
945  //
946  ntdll = GetModuleHandle( path.str );
947  }
948 
949  KMP_DEBUG_ASSERT( ntdll != NULL );
950  if ( ntdll != NULL ) {
951  NtQuerySystemInformation = (NtQuerySystemInformation_t) GetProcAddress( ntdll, "NtQuerySystemInformation" );
952  }
953  KMP_DEBUG_ASSERT( NtQuerySystemInformation != NULL );
954 
955 #if KMP_GROUP_AFFINITY
956  //
957  // Load kernel32.dll.
958  // Same caveat - must use full system path name.
959  //
960  if ( path_size > 0 && path_size < path.size ) {
961  //
962  // Truncate the buffer back to just the system path length,
963  // discarding "\\ntdll.dll", and replacing it with "kernel32.dll".
964  //
965  path.used = path_size;
966  __kmp_str_buf_print( & path, "\\%s", "kernel32.dll" );
967 
968  //
969  // Load kernel32.dll using full path.
970  //
971  kernel32 = GetModuleHandle( path.str );
972  KA_TRACE( 10, ("__kmp_runtime_initialize: kernel32.dll = %s\n", path.str ) );
973 
974  //
975  // Load the function pointers to kernel32.dll routines
976  // that may or may not exist on this system.
977  //
978  if ( kernel32 != NULL ) {
979  __kmp_GetActiveProcessorCount = (kmp_GetActiveProcessorCount_t) GetProcAddress( kernel32, "GetActiveProcessorCount" );
980  __kmp_GetActiveProcessorGroupCount = (kmp_GetActiveProcessorGroupCount_t) GetProcAddress( kernel32, "GetActiveProcessorGroupCount" );
981  __kmp_GetThreadGroupAffinity = (kmp_GetThreadGroupAffinity_t) GetProcAddress( kernel32, "GetThreadGroupAffinity" );
982  __kmp_SetThreadGroupAffinity = (kmp_SetThreadGroupAffinity_t) GetProcAddress( kernel32, "SetThreadGroupAffinity" );
983 
984  KA_TRACE( 10, ("__kmp_runtime_initialize: __kmp_GetActiveProcessorCount = %p\n", __kmp_GetActiveProcessorCount ) );
985  KA_TRACE( 10, ("__kmp_runtime_initialize: __kmp_GetActiveProcessorGroupCount = %p\n", __kmp_GetActiveProcessorGroupCount ) );
986  KA_TRACE( 10, ("__kmp_runtime_initialize:__kmp_GetThreadGroupAffinity = %p\n", __kmp_GetThreadGroupAffinity ) );
987  KA_TRACE( 10, ("__kmp_runtime_initialize: __kmp_SetThreadGroupAffinity = %p\n", __kmp_SetThreadGroupAffinity ) );
988  KA_TRACE( 10, ("__kmp_runtime_initialize: sizeof(kmp_affin_mask_t) = %d\n", sizeof(kmp_affin_mask_t) ) );
989 
990  //
991  // See if group affinity is supported on this system.
992  // If so, calculate the #groups and #procs.
993  //
994  // Group affinity was introduced with Windows* 7 OS and
995  // Windows* Server 2008 R2 OS.
996  //
997  if ( ( __kmp_GetActiveProcessorCount != NULL )
998  && ( __kmp_GetActiveProcessorGroupCount != NULL )
999  && ( __kmp_GetThreadGroupAffinity != NULL )
1000  && ( __kmp_SetThreadGroupAffinity != NULL )
1001  && ( ( __kmp_num_proc_groups
1002  = __kmp_GetActiveProcessorGroupCount() ) > 1 ) ) {
1003  //
1004  // Calculate the total number of active OS procs.
1005  //
1006  int i;
1007 
1008  KA_TRACE( 10, ("__kmp_runtime_initialize: %d processor groups detected\n", __kmp_num_proc_groups ) );
1009 
1010  __kmp_xproc = 0;
1011 
1012  for ( i = 0; i < __kmp_num_proc_groups; i++ ) {
1013  DWORD size = __kmp_GetActiveProcessorCount( i );
1014  __kmp_xproc += size;
1015  KA_TRACE( 10, ("__kmp_runtime_initialize: proc group %d size = %d\n", i, size ) );
1016  }
1017  }
1018  else {
1019  KA_TRACE( 10, ("__kmp_runtime_initialize: %d processor groups detected\n", __kmp_num_proc_groups ) );
1020  }
1021  }
1022  }
1023  if ( __kmp_num_proc_groups <= 1 ) {
1024  GetSystemInfo( & info );
1025  __kmp_xproc = info.dwNumberOfProcessors;
1026  }
1027 #else
1028  GetSystemInfo( & info );
1029  __kmp_xproc = info.dwNumberOfProcessors;
1030 #endif /* KMP_GROUP_AFFINITY */
1031 
1032  //
1033  // If the OS said there were 0 procs, take a guess and use a value of 2.
1034  // This is done for Linux* OS, also. Do we need error / warning?
1035  //
1036  if ( __kmp_xproc <= 0 ) {
1037  __kmp_xproc = 2;
1038  }
1039 
1040  KA_TRACE( 5, ("__kmp_runtime_initialize: total processors = %d\n", __kmp_xproc) );
1041 
1042  __kmp_str_buf_free( & path );
1043 
1044 #if USE_ITT_BUILD
1045  __kmp_itt_initialize();
1046 #endif /* USE_ITT_BUILD */
1047 
1048  __kmp_init_runtime = TRUE;
1049 } // __kmp_runtime_initialize
1050 
1051 void
1052 __kmp_runtime_destroy( void )
1053 {
1054  if ( ! __kmp_init_runtime ) {
1055  return;
1056  }
1057 
1058 #if USE_ITT_BUILD
1059  __kmp_itt_destroy();
1060 #endif /* USE_ITT_BUILD */
1061 
1062  /* we can't DeleteCriticalsection( & __kmp_win32_section ); */
1063  /* due to the KX_TRACE() commands */
1064  KA_TRACE( 40, ("__kmp_runtime_destroy\n" ));
1065 
1066  if( __kmp_gtid_threadprivate_key ) {
1067  TlsFree( __kmp_gtid_threadprivate_key );
1068  __kmp_gtid_threadprivate_key = 0;
1069  }
1070 
1071  __kmp_affinity_uninitialize();
1072  DeleteCriticalSection( & __kmp_win32_section );
1073 
1074  ntdll = NULL;
1075  NtQuerySystemInformation = NULL;
1076 
1077 #if KMP_ARCH_X86_64
1078  kernel32 = NULL;
1079  __kmp_GetActiveProcessorCount = NULL;
1080  __kmp_GetActiveProcessorGroupCount = NULL;
1081  __kmp_GetThreadGroupAffinity = NULL;
1082  __kmp_SetThreadGroupAffinity = NULL;
1083 #endif // KMP_ARCH_X86_64
1084 
1085  __kmp_init_runtime = FALSE;
1086 }
1087 
1088 
1089 void
1090 __kmp_terminate_thread( int gtid )
1091 {
1092  kmp_info_t *th = __kmp_threads[ gtid ];
1093 
1094  if( !th ) return;
1095 
1096  KA_TRACE( 10, ("__kmp_terminate_thread: kill (%d)\n", gtid ) );
1097 
1098  if (TerminateThread( th->th.th_info.ds.ds_thread, (DWORD) -1) == FALSE) {
1099  /* It's OK, the thread may have exited already */
1100  }
1101  __kmp_free_handle( th->th.th_info.ds.ds_thread );
1102 }
1103 
1104 /* ------------------------------------------------------------------------ */
1105 /* ------------------------------------------------------------------------ */
1106 
1107 void
1108 __kmp_clear_system_time( void )
1109 {
1110  BOOL status;
1111  LARGE_INTEGER time;
1112  status = QueryPerformanceCounter( & time );
1113  __kmp_win32_time = (kmp_int64) time.QuadPart;
1114 }
1115 
1116 void
1117 __kmp_initialize_system_tick( void )
1118 {
1119  {
1120  BOOL status;
1121  LARGE_INTEGER freq;
1122 
1123  status = QueryPerformanceFrequency( & freq );
1124  if (! status) {
1125  DWORD error = GetLastError();
1126  __kmp_msg(
1127  kmp_ms_fatal,
1128  KMP_MSG( FunctionError, "QueryPerformanceFrequency()" ),
1129  KMP_ERR( error ),
1130  __kmp_msg_null
1131  );
1132 
1133  }
1134  else {
1135  __kmp_win32_tick = ((double) 1.0) / (double) freq.QuadPart;
1136  }
1137  }
1138 }
1139 
1140 /* Calculate the elapsed wall clock time for the user */
1141 
1142 void
1143 __kmp_elapsed( double *t )
1144 {
1145  BOOL status;
1146  LARGE_INTEGER now;
1147  status = QueryPerformanceCounter( & now );
1148  *t = ((double) now.QuadPart) * __kmp_win32_tick;
1149 }
1150 
1151 /* Calculate the elapsed wall clock tick for the user */
1152 
1153 void
1154 __kmp_elapsed_tick( double *t )
1155 {
1156  *t = __kmp_win32_tick;
1157 }
1158 
1159 void
1160 __kmp_read_system_time( double *delta )
1161 {
1162 
1163  if (delta != NULL) {
1164  BOOL status;
1165  LARGE_INTEGER now;
1166 
1167  status = QueryPerformanceCounter( & now );
1168 
1169  *delta = ((double) (((kmp_int64) now.QuadPart) - __kmp_win32_time))
1170  * __kmp_win32_tick;
1171  }
1172 }
1173 
1174 /* ------------------------------------------------------------------------ */
1175 /* ------------------------------------------------------------------------ */
1176 
1177 void * __stdcall
1178 __kmp_launch_worker( void *arg )
1179 {
1180  volatile void *stack_data;
1181  void *exit_val;
1182  void *padding = 0;
1183  kmp_info_t *this_thr = (kmp_info_t *) arg;
1184  int gtid;
1185 
1186  gtid = this_thr->th.th_info.ds.ds_gtid;
1187  __kmp_gtid_set_specific( gtid );
1188 #ifdef KMP_TDATA_GTID
1189  #error "This define causes problems with LoadLibrary() + declspec(thread) " \
1190  "on Windows* OS. See CQ50564, tests kmp_load_library*.c and this MSDN " \
1191  "reference: http://support.microsoft.com/kb/118816"
1192  //__kmp_gtid = gtid;
1193 #endif
1194 
1195 #if USE_ITT_BUILD
1196  __kmp_itt_thread_name( gtid );
1197 #endif /* USE_ITT_BUILD */
1198 
1199  __kmp_affinity_set_init_mask( gtid, FALSE );
1200 
1201 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
1202  //
1203  // Set the FP control regs to be a copy of
1204  // the parallel initialization thread's.
1205  //
1206  __kmp_clear_x87_fpu_status_word();
1207  __kmp_load_x87_fpu_control_word( &__kmp_init_x87_fpu_control_word );
1208  __kmp_load_mxcsr( &__kmp_init_mxcsr );
1209 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
1210 
1211  if ( __kmp_stkoffset > 0 && gtid > 0 ) {
1212  padding = KMP_ALLOCA( gtid * __kmp_stkoffset );
1213  }
1214 
1215  KMP_FSYNC_RELEASING( &this_thr -> th.th_info.ds.ds_alive );
1216  this_thr -> th.th_info.ds.ds_thread_id = GetCurrentThreadId();
1217  TCW_4( this_thr -> th.th_info.ds.ds_alive, TRUE );
1218 
1219  if ( TCR_4(__kmp_gtid_mode) < 2 ) { // check stack only if it is used to get gtid
1220  TCW_PTR(this_thr->th.th_info.ds.ds_stackbase, &stack_data);
1221  KMP_ASSERT( this_thr -> th.th_info.ds.ds_stackgrow == FALSE );
1222  __kmp_check_stack_overlap( this_thr );
1223  }
1224  KMP_MB();
1225  exit_val = __kmp_launch_thread( this_thr );
1226  KMP_FSYNC_RELEASING( &this_thr -> th.th_info.ds.ds_alive );
1227  TCW_4( this_thr -> th.th_info.ds.ds_alive, FALSE );
1228  KMP_MB();
1229  return exit_val;
1230 }
1231 
1232 
1233 /* The monitor thread controls all of the threads in the complex */
1234 
1235 void * __stdcall
1236 __kmp_launch_monitor( void *arg )
1237 {
1238  DWORD wait_status;
1239  kmp_thread_t monitor;
1240  int status;
1241  int interval;
1242  kmp_info_t *this_thr = (kmp_info_t *) arg;
1243 
1244  KMP_DEBUG_ASSERT(__kmp_init_monitor);
1245  TCW_4( __kmp_init_monitor, 2 ); // AC: Signal the library that monitor has started
1246  // TODO: hide "2" in enum (like {true,false,started})
1247  this_thr -> th.th_info.ds.ds_thread_id = GetCurrentThreadId();
1248  TCW_4( this_thr -> th.th_info.ds.ds_alive, TRUE );
1249 
1250  KMP_MB(); /* Flush all pending memory write invalidates. */
1251  KA_TRACE( 10, ("__kmp_launch_monitor: launched\n" ) );
1252 
1253  monitor = GetCurrentThread();
1254 
1255  /* set thread priority */
1256  status = SetThreadPriority( monitor, THREAD_PRIORITY_HIGHEST );
1257  if (! status) {
1258  DWORD error = GetLastError();
1259  __kmp_msg(
1260  kmp_ms_fatal,
1261  KMP_MSG( CantSetThreadPriority ),
1262  KMP_ERR( error ),
1263  __kmp_msg_null
1264  );
1265  }
1266 
1267  /* register us as monitor */
1268  __kmp_gtid_set_specific( KMP_GTID_MONITOR );
1269 #ifdef KMP_TDATA_GTID
1270  #error "This define causes problems with LoadLibrary() + declspec(thread) " \
1271  "on Windows* OS. See CQ50564, tests kmp_load_library*.c and this MSDN " \
1272  "reference: http://support.microsoft.com/kb/118816"
1273  //__kmp_gtid = KMP_GTID_MONITOR;
1274 #endif
1275 
1276 #if USE_ITT_BUILD
1277  __kmp_itt_thread_ignore(); // Instruct Intel(R) Threading Tools to ignore monitor thread.
1278 #endif /* USE_ITT_BUILD */
1279 
1280  KMP_MB(); /* Flush all pending memory write invalidates. */
1281 
1282  interval = ( 1000 / __kmp_monitor_wakeups ); /* in milliseconds */
1283 
1284  while (! TCR_4(__kmp_global.g.g_done)) {
1285  /* This thread monitors the state of the system */
1286 
1287  KA_TRACE( 15, ( "__kmp_launch_monitor: update\n" ) );
1288 
1289  wait_status = WaitForSingleObject( __kmp_monitor_ev, interval );
1290 
1291  if (wait_status == WAIT_TIMEOUT) {
1292  TCW_4( __kmp_global.g.g_time.dt.t_value,
1293  TCR_4( __kmp_global.g.g_time.dt.t_value ) + 1 );
1294  }
1295 
1296  KMP_MB(); /* Flush all pending memory write invalidates. */
1297  }
1298 
1299  KA_TRACE( 10, ("__kmp_launch_monitor: finished\n" ) );
1300 
1301  status = SetThreadPriority( monitor, THREAD_PRIORITY_NORMAL );
1302  if (! status) {
1303  DWORD error = GetLastError();
1304  __kmp_msg(
1305  kmp_ms_fatal,
1306  KMP_MSG( CantSetThreadPriority ),
1307  KMP_ERR( error ),
1308  __kmp_msg_null
1309  );
1310  }
1311 
1312  if (__kmp_global.g.g_abort != 0) {
1313  /* now we need to terminate the worker threads */
1314  /* the value of t_abort is the signal we caught */
1315 
1316  int gtid;
1317 
1318  KA_TRACE( 10, ("__kmp_launch_monitor: terminate sig=%d\n", (__kmp_global.g.g_abort) ) );
1319 
1320  /* terminate the OpenMP worker threads */
1321  /* TODO this is not valid for sibling threads!!
1322  * the uber master might not be 0 anymore.. */
1323  for (gtid = 1; gtid < __kmp_threads_capacity; ++gtid)
1324  __kmp_terminate_thread( gtid );
1325 
1326  __kmp_cleanup();
1327 
1328  Sleep( 0 );
1329 
1330  KA_TRACE( 10, ("__kmp_launch_monitor: raise sig=%d\n", (__kmp_global.g.g_abort) ) );
1331 
1332  if (__kmp_global.g.g_abort > 0) {
1333  raise( __kmp_global.g.g_abort );
1334  }
1335  }
1336 
1337  TCW_4( this_thr -> th.th_info.ds.ds_alive, FALSE );
1338 
1339  KMP_MB();
1340  return arg;
1341 }
1342 
1343 void
1344 __kmp_create_worker( int gtid, kmp_info_t *th, size_t stack_size )
1345 {
1346  kmp_thread_t handle;
1347  DWORD idThread;
1348 
1349  KA_TRACE( 10, ("__kmp_create_worker: try to create thread (%d)\n", gtid ) );
1350 
1351  th->th.th_info.ds.ds_gtid = gtid;
1352 
1353  if ( KMP_UBER_GTID(gtid) ) {
1354  int stack_data;
1355 
1356  /* TODO: GetCurrentThread() returns a pseudo-handle that is unsuitable for other threads to use.
1357  Is it appropriate to just use GetCurrentThread? When should we close this handle? When
1358  unregistering the root?
1359  */
1360  {
1361  BOOL rc;
1362  rc = DuplicateHandle(
1363  GetCurrentProcess(),
1364  GetCurrentThread(),
1365  GetCurrentProcess(),
1366  &th->th.th_info.ds.ds_thread,
1367  0,
1368  FALSE,
1369  DUPLICATE_SAME_ACCESS
1370  );
1371  KMP_ASSERT( rc );
1372  KA_TRACE( 10, (" __kmp_create_worker: ROOT Handle duplicated, th = %p, handle = %" KMP_UINTPTR_SPEC "\n",
1373  (LPVOID)th,
1374  th->th.th_info.ds.ds_thread ) );
1375  th->th.th_info.ds.ds_thread_id = GetCurrentThreadId();
1376  }
1377  if ( TCR_4(__kmp_gtid_mode) < 2 ) { // check stack only if it is used to get gtid
1378  /* we will dynamically update the stack range if gtid_mode == 1 */
1379  TCW_PTR(th->th.th_info.ds.ds_stackbase, &stack_data);
1380  TCW_PTR(th->th.th_info.ds.ds_stacksize, 0);
1381  TCW_4(th->th.th_info.ds.ds_stackgrow, TRUE);
1382  __kmp_check_stack_overlap( th );
1383  }
1384  }
1385  else {
1386  KMP_MB(); /* Flush all pending memory write invalidates. */
1387 
1388  /* Set stack size for this thread now. */
1389  KA_TRACE( 10, ( "__kmp_create_worker: stack_size = %" KMP_SIZE_T_SPEC
1390  " bytes\n", stack_size ) );
1391 
1392  stack_size += gtid * __kmp_stkoffset;
1393 
1394  TCW_PTR(th->th.th_info.ds.ds_stacksize, stack_size);
1395  TCW_4(th->th.th_info.ds.ds_stackgrow, FALSE);
1396 
1397  KA_TRACE( 10, ( "__kmp_create_worker: (before) stack_size = %"
1398  KMP_SIZE_T_SPEC
1399  " bytes, &__kmp_launch_worker = %p, th = %p, "
1400  "&idThread = %p\n",
1401  (SIZE_T) stack_size,
1402  (LPTHREAD_START_ROUTINE) & __kmp_launch_worker,
1403  (LPVOID) th, &idThread ) );
1404 
1405  {
1406  handle = CreateThread( NULL, (SIZE_T) stack_size,
1407  (LPTHREAD_START_ROUTINE) __kmp_launch_worker,
1408  (LPVOID) th, STACK_SIZE_PARAM_IS_A_RESERVATION, &idThread );
1409  }
1410 
1411  KA_TRACE( 10, ( "__kmp_create_worker: (after) stack_size = %"
1412  KMP_SIZE_T_SPEC
1413  " bytes, &__kmp_launch_worker = %p, th = %p, "
1414  "idThread = %u, handle = %" KMP_UINTPTR_SPEC "\n",
1415  (SIZE_T) stack_size,
1416  (LPTHREAD_START_ROUTINE) & __kmp_launch_worker,
1417  (LPVOID) th, idThread, handle ) );
1418 
1419  {
1420  if ( handle == 0 ) {
1421  DWORD error = GetLastError();
1422  __kmp_msg(
1423  kmp_ms_fatal,
1424  KMP_MSG( CantCreateThread ),
1425  KMP_ERR( error ),
1426  __kmp_msg_null
1427  );
1428  } else {
1429  th->th.th_info.ds.ds_thread = handle;
1430  }
1431  }
1432  KMP_MB(); /* Flush all pending memory write invalidates. */
1433  }
1434 
1435  KA_TRACE( 10, ("__kmp_create_worker: done creating thread (%d)\n", gtid ) );
1436 }
1437 
1438 int
1439 __kmp_still_running(kmp_info_t *th) {
1440  return (WAIT_TIMEOUT == WaitForSingleObject( th->th.th_info.ds.ds_thread, 0));
1441 }
1442 
1443 void
1444 __kmp_create_monitor( kmp_info_t *th )
1445 {
1446  kmp_thread_t handle;
1447  DWORD idThread;
1448  int ideal, new_ideal;
1449  int caller_gtid = __kmp_get_gtid();
1450 
1451  KA_TRACE( 10, ("__kmp_create_monitor: try to create monitor\n" ) );
1452 
1453  KMP_MB(); /* Flush all pending memory write invalidates. */
1454 
1455  __kmp_monitor_ev = CreateEvent( NULL, TRUE, FALSE, NULL );
1456  if ( __kmp_monitor_ev == NULL ) {
1457  DWORD error = GetLastError();
1458  __kmp_msg(
1459  kmp_ms_fatal,
1460  KMP_MSG( CantCreateEvent ),
1461  KMP_ERR( error ),
1462  __kmp_msg_null
1463  );
1464  }; // if
1465 #if USE_ITT_BUILD
1466  __kmp_itt_system_object_created( __kmp_monitor_ev, "Event" );
1467 #endif /* USE_ITT_BUILD */
1468 
1469  th->th.th_info.ds.ds_tid = KMP_GTID_MONITOR;
1470  th->th.th_info.ds.ds_gtid = KMP_GTID_MONITOR;
1471 
1472  // FIXME - on Windows* OS, if __kmp_monitor_stksize = 0, figure out how
1473  // to automatically expand stacksize based on CreateThread error code.
1474  if ( __kmp_monitor_stksize == 0 ) {
1475  __kmp_monitor_stksize = KMP_DEFAULT_MONITOR_STKSIZE;
1476  }
1477  if ( __kmp_monitor_stksize < __kmp_sys_min_stksize ) {
1478  __kmp_monitor_stksize = __kmp_sys_min_stksize;
1479  }
1480 
1481  KA_TRACE( 10, ("__kmp_create_monitor: requested stacksize = %d bytes\n",
1482  (int) __kmp_monitor_stksize ) );
1483 
1484  TCW_4( __kmp_global.g.g_time.dt.t_value, 0 );
1485 
1486  handle = CreateThread( NULL, (SIZE_T) __kmp_monitor_stksize,
1487  (LPTHREAD_START_ROUTINE) __kmp_launch_monitor,
1488  (LPVOID) th, STACK_SIZE_PARAM_IS_A_RESERVATION, &idThread );
1489  if (handle == 0) {
1490  DWORD error = GetLastError();
1491  __kmp_msg(
1492  kmp_ms_fatal,
1493  KMP_MSG( CantCreateThread ),
1494  KMP_ERR( error ),
1495  __kmp_msg_null
1496  );
1497  }
1498  else
1499  th->th.th_info.ds.ds_thread = handle;
1500 
1501  KMP_MB(); /* Flush all pending memory write invalidates. */
1502 
1503  KA_TRACE( 10, ("__kmp_create_monitor: monitor created %p\n",
1504  (void *) th->th.th_info.ds.ds_thread ) );
1505 }
1506 
1507 /*
1508  Check to see if thread is still alive.
1509 
1510  NOTE: The ExitProcess(code) system call causes all threads to Terminate
1511  with a exit_val = code. Because of this we can not rely on
1512  exit_val having any particular value. So this routine may
1513  return STILL_ALIVE in exit_val even after the thread is dead.
1514 */
1515 
1516 int
1517 __kmp_is_thread_alive( kmp_info_t * th, DWORD *exit_val )
1518 {
1519  DWORD rc;
1520  rc = GetExitCodeThread( th->th.th_info.ds.ds_thread, exit_val );
1521  if ( rc == 0 ) {
1522  DWORD error = GetLastError();
1523  __kmp_msg(
1524  kmp_ms_fatal,
1525  KMP_MSG( FunctionError, "GetExitCodeThread()" ),
1526  KMP_ERR( error ),
1527  __kmp_msg_null
1528  );
1529  }; // if
1530  return ( *exit_val == STILL_ACTIVE );
1531 }
1532 
1533 
1534 void
1535 __kmp_exit_thread(
1536  int exit_status
1537 ) {
1538  ExitThread( exit_status );
1539 } // __kmp_exit_thread
1540 
1541 /*
1542  This is a common part for both __kmp_reap_worker() and __kmp_reap_monitor().
1543 */
1544 static void
1545 __kmp_reap_common( kmp_info_t * th )
1546 {
1547  DWORD exit_val;
1548 
1549  KMP_MB(); /* Flush all pending memory write invalidates. */
1550 
1551  KA_TRACE( 10, ( "__kmp_reap_common: try to reap (%d)\n", th->th.th_info.ds.ds_gtid ) );
1552 
1553  /*
1554  2006-10-19:
1555 
1556  There are two opposite situations:
1557 
1558  1. Windows* OS keep thread alive after it resets ds_alive flag and exits from thread
1559  function. (For example, see C70770/Q394281 "unloading of dll based on OMP is very
1560  slow".)
1561  2. Windows* OS may kill thread before it resets ds_alive flag.
1562 
1563  Right solution seems to be waiting for *either* thread termination *or* ds_alive resetting.
1564 
1565  */
1566 
1567  {
1568  // TODO: This code is very similar to KMP_WAIT_YIELD. Need to generalize KMP_WAIT_YIELD to
1569  // cover this usage also.
1570  void * obj = NULL;
1571  register kmp_uint32 spins;
1572 #if USE_ITT_BUILD
1573  KMP_FSYNC_SPIN_INIT( obj, (void*) & th->th.th_info.ds.ds_alive );
1574 #endif /* USE_ITT_BUILD */
1575  KMP_INIT_YIELD( spins );
1576  do {
1577 #if USE_ITT_BUILD
1578  KMP_FSYNC_SPIN_PREPARE( obj );
1579 #endif /* USE_ITT_BUILD */
1580  __kmp_is_thread_alive( th, &exit_val );
1581  KMP_YIELD( TCR_4(__kmp_nth) > __kmp_avail_proc );
1582  KMP_YIELD_SPIN( spins );
1583  } while ( exit_val == STILL_ACTIVE && TCR_4( th->th.th_info.ds.ds_alive ) );
1584 #if USE_ITT_BUILD
1585  if ( exit_val == STILL_ACTIVE ) {
1586  KMP_FSYNC_CANCEL( obj );
1587  } else {
1588  KMP_FSYNC_SPIN_ACQUIRED( obj );
1589  }; // if
1590 #endif /* USE_ITT_BUILD */
1591  }
1592 
1593  __kmp_free_handle( th->th.th_info.ds.ds_thread );
1594 
1595  /*
1596  * NOTE: The ExitProcess(code) system call causes all threads to Terminate
1597  * with a exit_val = code. Because of this we can not rely on
1598  * exit_val having any particular value.
1599  */
1600  if ( exit_val == STILL_ACTIVE ) {
1601  KA_TRACE( 1, ( "__kmp_reap_common: thread still active.\n" ) );
1602  } else if ( (void *) exit_val != (void *) th) {
1603  KA_TRACE( 1, ( "__kmp_reap_common: ExitProcess / TerminateThread used?\n" ) );
1604  }; // if
1605 
1606  KA_TRACE( 10,
1607  (
1608  "__kmp_reap_common: done reaping (%d), handle = %" KMP_UINTPTR_SPEC "\n",
1609  th->th.th_info.ds.ds_gtid,
1610  th->th.th_info.ds.ds_thread
1611  )
1612  );
1613 
1614  th->th.th_info.ds.ds_thread = 0;
1615  th->th.th_info.ds.ds_tid = KMP_GTID_DNE;
1616  th->th.th_info.ds.ds_gtid = KMP_GTID_DNE;
1617  th->th.th_info.ds.ds_thread_id = 0;
1618 
1619  KMP_MB(); /* Flush all pending memory write invalidates. */
1620 }
1621 
1622 void
1623 __kmp_reap_monitor( kmp_info_t *th )
1624 {
1625  int status;
1626 
1627  KA_TRACE( 10, ("__kmp_reap_monitor: try to reap %p\n",
1628  (void *) th->th.th_info.ds.ds_thread ) );
1629 
1630  // If monitor has been created, its tid and gtid should be KMP_GTID_MONITOR.
1631  // If both tid and gtid are 0, it means the monitor did not ever start.
1632  // If both tid and gtid are KMP_GTID_DNE, the monitor has been shut down.
1633  KMP_DEBUG_ASSERT( th->th.th_info.ds.ds_tid == th->th.th_info.ds.ds_gtid );
1634  if ( th->th.th_info.ds.ds_gtid != KMP_GTID_MONITOR ) {
1635  return;
1636  }; // if
1637 
1638  KMP_MB(); /* Flush all pending memory write invalidates. */
1639 
1640  status = SetEvent( __kmp_monitor_ev );
1641  if ( status == FALSE ) {
1642  DWORD error = GetLastError();
1643  __kmp_msg(
1644  kmp_ms_fatal,
1645  KMP_MSG( CantSetEvent ),
1646  KMP_ERR( error ),
1647  __kmp_msg_null
1648  );
1649  }
1650  KA_TRACE( 10, ( "__kmp_reap_monitor: reaping thread (%d)\n", th->th.th_info.ds.ds_gtid ) );
1651  __kmp_reap_common( th );
1652 
1653  __kmp_free_handle( __kmp_monitor_ev );
1654 
1655  KMP_MB(); /* Flush all pending memory write invalidates. */
1656 }
1657 
1658 void
1659 __kmp_reap_worker( kmp_info_t * th )
1660 {
1661  KA_TRACE( 10, ( "__kmp_reap_worker: reaping thread (%d)\n", th->th.th_info.ds.ds_gtid ) );
1662  __kmp_reap_common( th );
1663 }
1664 
1665 /* ------------------------------------------------------------------------ */
1666 /* ------------------------------------------------------------------------ */
1667 
1668 #if KMP_HANDLE_SIGNALS
1669 
1670 
1671 static void
1672 __kmp_team_handler( int signo )
1673 {
1674  if ( __kmp_global.g.g_abort == 0 ) {
1675  // Stage 1 signal handler, let's shut down all of the threads.
1676  if ( __kmp_debug_buf ) {
1677  __kmp_dump_debug_buffer();
1678  }; // if
1679  KMP_MB(); // Flush all pending memory write invalidates.
1680  TCW_4( __kmp_global.g.g_abort, signo );
1681  KMP_MB(); // Flush all pending memory write invalidates.
1682  TCW_4( __kmp_global.g.g_done, TRUE );
1683  KMP_MB(); // Flush all pending memory write invalidates.
1684  }
1685 } // __kmp_team_handler
1686 
1687 
1688 
1689 static
1690 sig_func_t __kmp_signal( int signum, sig_func_t handler ) {
1691  sig_func_t old = signal( signum, handler );
1692  if ( old == SIG_ERR ) {
1693  int error = errno;
1694  __kmp_msg( kmp_ms_fatal, KMP_MSG( FunctionError, "signal" ), KMP_ERR( error ), __kmp_msg_null );
1695  }; // if
1696  return old;
1697 }
1698 
1699 static void
1700 __kmp_install_one_handler(
1701  int sig,
1702  sig_func_t handler,
1703  int parallel_init
1704 ) {
1705  sig_func_t old;
1706  KMP_MB(); /* Flush all pending memory write invalidates. */
1707  KB_TRACE( 60, ("__kmp_install_one_handler: called: sig=%d\n", sig ) );
1708  if ( parallel_init ) {
1709  old = __kmp_signal( sig, handler );
1710  // SIG_DFL on Windows* OS in NULL or 0.
1711  if ( old == __kmp_sighldrs[ sig ] ) {
1712  __kmp_siginstalled[ sig ] = 1;
1713  } else {
1714  // Restore/keep user's handler if one previously installed.
1715  old = __kmp_signal( sig, old );
1716  }; // if
1717  } else {
1718  // Save initial/system signal handlers to see if user handlers installed.
1719  // 2009-09-23: It is a dead code. On Windows* OS __kmp_install_signals called once with
1720  // parallel_init == TRUE.
1721  old = __kmp_signal( sig, SIG_DFL );
1722  __kmp_sighldrs[ sig ] = old;
1723  __kmp_signal( sig, old );
1724  }; // if
1725  KMP_MB(); /* Flush all pending memory write invalidates. */
1726 } // __kmp_install_one_handler
1727 
1728 static void
1729 __kmp_remove_one_handler( int sig ) {
1730  if ( __kmp_siginstalled[ sig ] ) {
1731  sig_func_t old;
1732  KMP_MB(); // Flush all pending memory write invalidates.
1733  KB_TRACE( 60, ( "__kmp_remove_one_handler: called: sig=%d\n", sig ) );
1734  old = __kmp_signal( sig, __kmp_sighldrs[ sig ] );
1735  if ( old != __kmp_team_handler ) {
1736  KB_TRACE( 10, ( "__kmp_remove_one_handler: oops, not our handler, restoring: sig=%d\n", sig ) );
1737  old = __kmp_signal( sig, old );
1738  }; // if
1739  __kmp_sighldrs[ sig ] = NULL;
1740  __kmp_siginstalled[ sig ] = 0;
1741  KMP_MB(); // Flush all pending memory write invalidates.
1742  }; // if
1743 } // __kmp_remove_one_handler
1744 
1745 
1746 void
1747 __kmp_install_signals( int parallel_init )
1748 {
1749  KB_TRACE( 10, ( "__kmp_install_signals: called\n" ) );
1750  if ( ! __kmp_handle_signals ) {
1751  KB_TRACE( 10, ( "__kmp_install_signals: KMP_HANDLE_SIGNALS is false - handlers not installed\n" ) );
1752  return;
1753  }; // if
1754  __kmp_install_one_handler( SIGINT, __kmp_team_handler, parallel_init );
1755  __kmp_install_one_handler( SIGILL, __kmp_team_handler, parallel_init );
1756  __kmp_install_one_handler( SIGABRT, __kmp_team_handler, parallel_init );
1757  __kmp_install_one_handler( SIGFPE, __kmp_team_handler, parallel_init );
1758  __kmp_install_one_handler( SIGSEGV, __kmp_team_handler, parallel_init );
1759  __kmp_install_one_handler( SIGTERM, __kmp_team_handler, parallel_init );
1760 } // __kmp_install_signals
1761 
1762 
1763 void
1764 __kmp_remove_signals( void )
1765 {
1766  int sig;
1767  KB_TRACE( 10, ("__kmp_remove_signals: called\n" ) );
1768  for ( sig = 1; sig < NSIG; ++ sig ) {
1769  __kmp_remove_one_handler( sig );
1770  }; // for sig
1771 } // __kmp_remove_signals
1772 
1773 
1774 #endif // KMP_HANDLE_SIGNALS
1775 
1776 /* Put the thread to sleep for a time period */
1777 void
1778 __kmp_thread_sleep( int millis )
1779 {
1780  DWORD status;
1781 
1782  status = SleepEx( (DWORD) millis, FALSE );
1783  if ( status ) {
1784  DWORD error = GetLastError();
1785  __kmp_msg(
1786  kmp_ms_fatal,
1787  KMP_MSG( FunctionError, "SleepEx()" ),
1788  KMP_ERR( error ),
1789  __kmp_msg_null
1790  );
1791  }
1792 }
1793 
1794 /* Determine whether the given address is mapped into the current address space. */
1795 int
1796 __kmp_is_address_mapped( void * addr )
1797 {
1798  DWORD status;
1799  MEMORY_BASIC_INFORMATION lpBuffer;
1800  SIZE_T dwLength;
1801 
1802  dwLength = sizeof(MEMORY_BASIC_INFORMATION);
1803 
1804  status = VirtualQuery( addr, &lpBuffer, dwLength );
1805 
1806  return !((( lpBuffer.State == MEM_RESERVE) || ( lpBuffer.State == MEM_FREE )) ||
1807  (( lpBuffer.Protect == PAGE_NOACCESS ) || ( lpBuffer.Protect == PAGE_EXECUTE )));
1808 }
1809 
1810 kmp_uint64
1811 __kmp_hardware_timestamp(void)
1812 {
1813  kmp_uint64 r = 0;
1814 
1815  QueryPerformanceCounter((LARGE_INTEGER*) &r);
1816  return r;
1817 }
1818 
1819 /* Free handle and check the error code */
1820 void
1821 __kmp_free_handle( kmp_thread_t tHandle )
1822 {
1823 /* called with parameter type HANDLE also, thus suppose kmp_thread_t defined as HANDLE */
1824  BOOL rc;
1825  rc = CloseHandle( tHandle );
1826  if ( !rc ) {
1827  DWORD error = GetLastError();
1828  __kmp_msg(
1829  kmp_ms_fatal,
1830  KMP_MSG( CantCloseHandle ),
1831  KMP_ERR( error ),
1832  __kmp_msg_null
1833  );
1834  }
1835 }
1836 
1837 int
1838 __kmp_get_load_balance( int max ) {
1839 
1840  static ULONG glb_buff_size = 100 * 1024;
1841 
1842  static int glb_running_threads = 0; /* Saved count of the running threads for the thread balance algortihm */
1843  static double glb_call_time = 0; /* Thread balance algorithm call time */
1844 
1845  int running_threads = 0; // Number of running threads in the system.
1846  NTSTATUS status = 0;
1847  ULONG buff_size = 0;
1848  ULONG info_size = 0;
1849  void * buffer = NULL;
1850  PSYSTEM_PROCESS_INFORMATION spi = NULL;
1851  int first_time = 1;
1852 
1853  double call_time = 0.0; //start, finish;
1854 
1855  __kmp_elapsed( & call_time );
1856 
1857  if ( glb_call_time &&
1858  ( call_time - glb_call_time < __kmp_load_balance_interval ) ) {
1859  running_threads = glb_running_threads;
1860  goto finish;
1861  }
1862  glb_call_time = call_time;
1863 
1864  // Do not spend time on running algorithm if we have a permanent error.
1865  if ( NtQuerySystemInformation == NULL ) {
1866  running_threads = -1;
1867  goto finish;
1868  }; // if
1869 
1870  if ( max <= 0 ) {
1871  max = INT_MAX;
1872  }; // if
1873 
1874  do {
1875 
1876  if ( first_time ) {
1877  buff_size = glb_buff_size;
1878  } else {
1879  buff_size = 2 * buff_size;
1880  }
1881 
1882  buffer = KMP_INTERNAL_REALLOC( buffer, buff_size );
1883  if ( buffer == NULL ) {
1884  running_threads = -1;
1885  goto finish;
1886  }; // if
1887  status = NtQuerySystemInformation( SystemProcessInformation, buffer, buff_size, & info_size );
1888  first_time = 0;
1889 
1890  } while ( status == STATUS_INFO_LENGTH_MISMATCH );
1891  glb_buff_size = buff_size;
1892 
1893  #define CHECK( cond ) \
1894  { \
1895  KMP_DEBUG_ASSERT( cond ); \
1896  if ( ! ( cond ) ) { \
1897  running_threads = -1; \
1898  goto finish; \
1899  } \
1900  }
1901 
1902  CHECK( buff_size >= info_size );
1903  spi = PSYSTEM_PROCESS_INFORMATION( buffer );
1904  for ( ; ; ) {
1905  ptrdiff_t offset = uintptr_t( spi ) - uintptr_t( buffer );
1906  CHECK( 0 <= offset && offset + sizeof( SYSTEM_PROCESS_INFORMATION ) < info_size );
1907  HANDLE pid = spi->ProcessId;
1908  ULONG num = spi->NumberOfThreads;
1909  CHECK( num >= 1 );
1910  size_t spi_size = sizeof( SYSTEM_PROCESS_INFORMATION ) + sizeof( SYSTEM_THREAD ) * ( num - 1 );
1911  CHECK( offset + spi_size < info_size ); // Make sure process info record fits the buffer.
1912  if ( spi->NextEntryOffset != 0 ) {
1913  CHECK( spi_size <= spi->NextEntryOffset ); // And do not overlap with the next record.
1914  }; // if
1915  // pid == 0 corresponds to the System Idle Process. It always has running threads
1916  // on all cores. So, we don't consider the running threads of this process.
1917  if ( pid != 0 ) {
1918  for ( int i = 0; i < num; ++ i ) {
1919  THREAD_STATE state = spi->Threads[ i ].State;
1920  // Count threads that have Ready or Running state.
1921  // !!! TODO: Why comment does not match the code???
1922  if ( state == StateRunning ) {
1923  ++ running_threads;
1924  // Stop counting running threads if the number is already greater than
1925  // the number of available cores
1926  if ( running_threads >= max ) {
1927  goto finish;
1928  }
1929  } // if
1930  }; // for i
1931  } // if
1932  if ( spi->NextEntryOffset == 0 ) {
1933  break;
1934  }; // if
1935  spi = PSYSTEM_PROCESS_INFORMATION( uintptr_t( spi ) + spi->NextEntryOffset );
1936  }; // forever
1937 
1938  #undef CHECK
1939 
1940  finish: // Clean up and exit.
1941 
1942  if ( buffer != NULL ) {
1943  KMP_INTERNAL_FREE( buffer );
1944  }; // if
1945 
1946  glb_running_threads = running_threads;
1947 
1948  return running_threads;
1949 
1950 } //__kmp_get_load_balance()
1951