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 /* This routine signals the thread specified by target_gtid to wake up
459  * after setting the sleep bit indicated by the flag argument to FALSE
460  */
461 template <class C>
462 static inline void __kmp_resume_template( int target_gtid, C *flag )
463 {
464  kmp_info_t *th = __kmp_threads[target_gtid];
465  int status;
466 
467 #ifdef KMP_DEBUG
468  int gtid = TCR_4(__kmp_init_gtid) ? __kmp_get_gtid() : -1;
469 #endif
470 
471  KF_TRACE( 30, ( "__kmp_resume_template: T#%d wants to wakeup T#%d enter\n", gtid, target_gtid ) );
472 
473  __kmp_suspend_initialize_thread( th );
474  __kmp_win32_mutex_lock( &th->th.th_suspend_mx );
475 
476  if (!flag) {
477  flag = (C *)th->th.th_sleep_loc;
478  }
479 
480  if (!flag) {
481  KF_TRACE( 5, ( "__kmp_resume_template: T#%d exiting, thread T#%d already awake: flag's loc(%p)\n",
482  gtid, target_gtid, NULL ) );
483  __kmp_win32_mutex_unlock( &th->th.th_suspend_mx );
484  return;
485  }
486  else {
487  typename C::flag_t old_spin = flag->unset_sleeping();
488  if ( !flag->is_sleeping_val(old_spin) ) {
489  KF_TRACE( 5, ( "__kmp_resume_template: T#%d exiting, thread T#%d already awake: flag's loc(%p): "
490  "%u => %u\n",
491  gtid, target_gtid, flag->get(), old_spin, *(flag->get()) ) );
492  __kmp_win32_mutex_unlock( &th->th.th_suspend_mx );
493  return;
494  }
495  }
496  TCW_PTR(th->th.th_sleep_loc, NULL);
497  KF_TRACE( 5, ( "__kmp_resume_template: T#%d about to wakeup T#%d, reset sleep bit for flag's loc(%p)\n",
498  gtid, target_gtid, flag->get() ) );
499 
500 
501  __kmp_win32_cond_signal( &th->th.th_suspend_cv );
502  __kmp_win32_mutex_unlock( &th->th.th_suspend_mx );
503 
504  KF_TRACE( 30, ( "__kmp_resume_template: T#%d exiting after signaling wake up for T#%d\n",
505  gtid, target_gtid ) );
506 }
507 
508 void __kmp_resume_32(int target_gtid, kmp_flag_32 *flag) {
509  __kmp_resume_template(target_gtid, flag);
510 }
511 void __kmp_resume_64(int target_gtid, kmp_flag_64 *flag) {
512  __kmp_resume_template(target_gtid, flag);
513 }
514 void __kmp_resume_oncore(int target_gtid, kmp_flag_oncore *flag) {
515  __kmp_resume_template(target_gtid, flag);
516 }
517 
518 /* ------------------------------------------------------------------------ */
519 /* ------------------------------------------------------------------------ */
520 
521 void
522 __kmp_yield( int cond )
523 {
524  if (cond)
525  Sleep(0);
526 }
527 
528 /* ------------------------------------------------------------------------ */
529 /* ------------------------------------------------------------------------ */
530 
531 void
532 __kmp_gtid_set_specific( int gtid )
533 {
534  KA_TRACE( 50, ("__kmp_gtid_set_specific: T#%d key:%d\n",
535  gtid, __kmp_gtid_threadprivate_key ));
536  KMP_ASSERT( __kmp_init_runtime );
537  if( ! TlsSetValue( __kmp_gtid_threadprivate_key, (LPVOID)(gtid+1)) )
538  KMP_FATAL( TLSSetValueFailed );
539 }
540 
541 int
542 __kmp_gtid_get_specific()
543 {
544  int gtid;
545  if( !__kmp_init_runtime ) {
546  KA_TRACE( 50, ("__kmp_get_specific: runtime shutdown, returning KMP_GTID_SHUTDOWN\n" ) );
547  return KMP_GTID_SHUTDOWN;
548  }
549  gtid = (int)(kmp_intptr_t)TlsGetValue( __kmp_gtid_threadprivate_key );
550  if ( gtid == 0 ) {
551  gtid = KMP_GTID_DNE;
552  }
553  else {
554  gtid--;
555  }
556  KA_TRACE( 50, ("__kmp_gtid_get_specific: key:%d gtid:%d\n",
557  __kmp_gtid_threadprivate_key, gtid ));
558  return gtid;
559 }
560 
561 /* ------------------------------------------------------------------------ */
562 /* ------------------------------------------------------------------------ */
563 
564 #if KMP_GROUP_AFFINITY
565 
566 //
567 // Only 1 DWORD in the mask should have any procs set.
568 // Return the appropriate index, or -1 for an invalid mask.
569 //
570 int
571 __kmp_get_proc_group( kmp_affin_mask_t const *mask )
572 {
573  int i;
574  int group = -1;
575  for (i = 0; i < __kmp_num_proc_groups; i++) {
576  if (mask[i] == 0) {
577  continue;
578  }
579  if (group >= 0) {
580  return -1;
581  }
582  group = i;
583  }
584  return group;
585 }
586 
587 #endif /* KMP_GROUP_AFFINITY */
588 
589 int
590 __kmp_set_system_affinity( kmp_affin_mask_t const *mask, int abort_on_error )
591 {
592 
593 #if KMP_GROUP_AFFINITY
594 
595  if (__kmp_num_proc_groups > 1) {
596  //
597  // Check for a valid mask.
598  //
599  GROUP_AFFINITY ga;
600  int group = __kmp_get_proc_group( mask );
601  if (group < 0) {
602  if (abort_on_error) {
603  KMP_FATAL(AffinityInvalidMask, "kmp_set_affinity");
604  }
605  return -1;
606  }
607 
608  //
609  // Transform the bit vector into a GROUP_AFFINITY struct
610  // and make the system call to set affinity.
611  //
612  ga.Group = group;
613  ga.Mask = mask[group];
614  ga.Reserved[0] = ga.Reserved[1] = ga.Reserved[2] = 0;
615 
616  KMP_DEBUG_ASSERT(__kmp_SetThreadGroupAffinity != NULL);
617  if (__kmp_SetThreadGroupAffinity(GetCurrentThread(), &ga, NULL) == 0) {
618  DWORD error = GetLastError();
619  if (abort_on_error) {
620  __kmp_msg(
621  kmp_ms_fatal,
622  KMP_MSG( CantSetThreadAffMask ),
623  KMP_ERR( error ),
624  __kmp_msg_null
625  );
626  }
627  return error;
628  }
629  }
630  else
631 
632 #endif /* KMP_GROUP_AFFINITY */
633 
634  {
635  if (!SetThreadAffinityMask( GetCurrentThread(), *mask )) {
636  DWORD error = GetLastError();
637  if (abort_on_error) {
638  __kmp_msg(
639  kmp_ms_fatal,
640  KMP_MSG( CantSetThreadAffMask ),
641  KMP_ERR( error ),
642  __kmp_msg_null
643  );
644  }
645  return error;
646  }
647  }
648  return 0;
649 }
650 
651 int
652 __kmp_get_system_affinity( kmp_affin_mask_t *mask, int abort_on_error )
653 {
654 
655 #if KMP_GROUP_AFFINITY
656 
657  if (__kmp_num_proc_groups > 1) {
658  KMP_CPU_ZERO(mask);
659  GROUP_AFFINITY ga;
660  KMP_DEBUG_ASSERT(__kmp_GetThreadGroupAffinity != NULL);
661 
662  if (__kmp_GetThreadGroupAffinity(GetCurrentThread(), &ga) == 0) {
663  DWORD error = GetLastError();
664  if (abort_on_error) {
665  __kmp_msg(
666  kmp_ms_fatal,
667  KMP_MSG(FunctionError, "GetThreadGroupAffinity()"),
668  KMP_ERR(error),
669  __kmp_msg_null
670  );
671  }
672  return error;
673  }
674 
675  if ((ga.Group < 0) || (ga.Group > __kmp_num_proc_groups)
676  || (ga.Mask == 0)) {
677  return -1;
678  }
679 
680  mask[ga.Group] = ga.Mask;
681  }
682  else
683 
684 #endif /* KMP_GROUP_AFFINITY */
685 
686  {
687  kmp_affin_mask_t newMask, sysMask, retval;
688 
689  if (!GetProcessAffinityMask(GetCurrentProcess(), &newMask, &sysMask)) {
690  DWORD error = GetLastError();
691  if (abort_on_error) {
692  __kmp_msg(
693  kmp_ms_fatal,
694  KMP_MSG(FunctionError, "GetProcessAffinityMask()"),
695  KMP_ERR(error),
696  __kmp_msg_null
697  );
698  }
699  return error;
700  }
701  retval = SetThreadAffinityMask(GetCurrentThread(), newMask);
702  if (! retval) {
703  DWORD error = GetLastError();
704  if (abort_on_error) {
705  __kmp_msg(
706  kmp_ms_fatal,
707  KMP_MSG(FunctionError, "SetThreadAffinityMask()"),
708  KMP_ERR(error),
709  __kmp_msg_null
710  );
711  }
712  return error;
713  }
714  newMask = SetThreadAffinityMask(GetCurrentThread(), retval);
715  if (! newMask) {
716  DWORD error = GetLastError();
717  if (abort_on_error) {
718  __kmp_msg(
719  kmp_ms_fatal,
720  KMP_MSG(FunctionError, "SetThreadAffinityMask()"),
721  KMP_ERR(error),
722  __kmp_msg_null
723  );
724  }
725  }
726  *mask = retval;
727  }
728  return 0;
729 }
730 
731 void
732 __kmp_affinity_bind_thread( int proc )
733 {
734 
735 #if KMP_GROUP_AFFINITY
736 
737  if (__kmp_num_proc_groups > 1) {
738  //
739  // Form the GROUP_AFFINITY struct directly, rather than filling
740  // out a bit vector and calling __kmp_set_system_affinity().
741  //
742  GROUP_AFFINITY ga;
743  KMP_DEBUG_ASSERT((proc >= 0) && (proc < (__kmp_num_proc_groups
744  * CHAR_BIT * sizeof(DWORD_PTR))));
745  ga.Group = proc / (CHAR_BIT * sizeof(DWORD_PTR));
746  ga.Mask = (unsigned long long)1 << (proc % (CHAR_BIT * sizeof(DWORD_PTR)));
747  ga.Reserved[0] = ga.Reserved[1] = ga.Reserved[2] = 0;
748 
749  KMP_DEBUG_ASSERT(__kmp_SetThreadGroupAffinity != NULL);
750  if (__kmp_SetThreadGroupAffinity(GetCurrentThread(), &ga, NULL) == 0) {
751  DWORD error = GetLastError();
752  if (__kmp_affinity_verbose) { // AC: continue silently if not verbose
753  __kmp_msg(
754  kmp_ms_warning,
755  KMP_MSG( CantSetThreadAffMask ),
756  KMP_ERR( error ),
757  __kmp_msg_null
758  );
759  }
760  }
761  }
762  else
763 
764 #endif /* KMP_GROUP_AFFINITY */
765 
766  {
767  kmp_affin_mask_t mask;
768  KMP_CPU_ZERO(&mask);
769  KMP_CPU_SET(proc, &mask);
770  __kmp_set_system_affinity(&mask, TRUE);
771  }
772 }
773 
774 void
775 __kmp_affinity_determine_capable( const char *env_var )
776 {
777  //
778  // All versions of Windows* OS (since Win '95) support SetThreadAffinityMask().
779  //
780 
781 #if KMP_GROUP_AFFINITY
782  KMP_AFFINITY_ENABLE(__kmp_num_proc_groups*sizeof(kmp_affin_mask_t));
783 #else
784  KMP_AFFINITY_ENABLE(sizeof(kmp_affin_mask_t));
785 #endif
786 
787  KA_TRACE( 10, (
788  "__kmp_affinity_determine_capable: "
789  "Windows* OS affinity interface functional (mask size = %" KMP_SIZE_T_SPEC ").\n",
790  __kmp_affin_mask_size
791  ) );
792 }
793 
794 double
795 __kmp_read_cpu_time( void )
796 {
797  FILETIME CreationTime, ExitTime, KernelTime, UserTime;
798  int status;
799  double cpu_time;
800 
801  cpu_time = 0;
802 
803  status = GetProcessTimes( GetCurrentProcess(), &CreationTime,
804  &ExitTime, &KernelTime, &UserTime );
805 
806  if (status) {
807  double sec = 0;
808 
809  sec += KernelTime.dwHighDateTime;
810  sec += UserTime.dwHighDateTime;
811 
812  /* Shift left by 32 bits */
813  sec *= (double) (1 << 16) * (double) (1 << 16);
814 
815  sec += KernelTime.dwLowDateTime;
816  sec += UserTime.dwLowDateTime;
817 
818  cpu_time += (sec * 100.0) / KMP_NSEC_PER_SEC;
819  }
820 
821  return cpu_time;
822 }
823 
824 int
825 __kmp_read_system_info( struct kmp_sys_info *info )
826 {
827  info->maxrss = 0; /* the maximum resident set size utilized (in kilobytes) */
828  info->minflt = 0; /* the number of page faults serviced without any I/O */
829  info->majflt = 0; /* the number of page faults serviced that required I/O */
830  info->nswap = 0; /* the number of times a process was "swapped" out of memory */
831  info->inblock = 0; /* the number of times the file system had to perform input */
832  info->oublock = 0; /* the number of times the file system had to perform output */
833  info->nvcsw = 0; /* the number of times a context switch was voluntarily */
834  info->nivcsw = 0; /* the number of times a context switch was forced */
835 
836  return 1;
837 }
838 
839 /* ------------------------------------------------------------------------ */
840 /* ------------------------------------------------------------------------ */
841 
842 
843 void
844 __kmp_runtime_initialize( void )
845 {
846  SYSTEM_INFO info;
847  kmp_str_buf_t path;
848  UINT path_size;
849 
850  if ( __kmp_init_runtime ) {
851  return;
852  };
853 
854 #if KMP_DYNAMIC_LIB
855  /* Pin dynamic library for the lifetime of application */
856  {
857  // First, turn off error message boxes
858  UINT err_mode = SetErrorMode (SEM_FAILCRITICALERRORS);
859  HMODULE h;
860  BOOL ret = GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
861  |GET_MODULE_HANDLE_EX_FLAG_PIN,
862  (LPCTSTR)&__kmp_serial_initialize, &h);
863  KMP_DEBUG_ASSERT2(h && ret, "OpenMP RTL cannot find itself loaded");
864  SetErrorMode (err_mode); // Restore error mode
865  KA_TRACE( 10, ("__kmp_runtime_initialize: dynamic library pinned\n") );
866  }
867 #endif
868 
869  InitializeCriticalSection( & __kmp_win32_section );
870 #if USE_ITT_BUILD
871  __kmp_itt_system_object_created( & __kmp_win32_section, "Critical Section" );
872 #endif /* USE_ITT_BUILD */
873  __kmp_initialize_system_tick();
874 
875  #if (KMP_ARCH_X86 || KMP_ARCH_X86_64)
876  if ( ! __kmp_cpuinfo.initialized ) {
877  __kmp_query_cpuid( & __kmp_cpuinfo );
878  }; // if
879  #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
880 
881  /* Set up minimum number of threads to switch to TLS gtid */
882  #if KMP_OS_WINDOWS && ! defined KMP_DYNAMIC_LIB
883  // Windows* OS, static library.
884  /*
885  New thread may use stack space previously used by another thread, currently terminated.
886  On Windows* OS, in case of static linking, we do not know the moment of thread termination,
887  and our structures (__kmp_threads and __kmp_root arrays) are still keep info about dead
888  threads. This leads to problem in __kmp_get_global_thread_id() function: it wrongly
889  finds gtid (by searching through stack addresses of all known threads) for unregistered
890  foreign tread.
891 
892  Setting __kmp_tls_gtid_min to 0 workarounds this problem: __kmp_get_global_thread_id()
893  does not search through stacks, but get gtid from TLS immediately.
894 
895  --ln
896  */
897  __kmp_tls_gtid_min = 0;
898  #else
899  __kmp_tls_gtid_min = KMP_TLS_GTID_MIN;
900  #endif
901 
902  /* for the static library */
903  if ( !__kmp_gtid_threadprivate_key ) {
904  __kmp_gtid_threadprivate_key = TlsAlloc();
905  if( __kmp_gtid_threadprivate_key == TLS_OUT_OF_INDEXES ) {
906  KMP_FATAL( TLSOutOfIndexes );
907  }
908  }
909 
910 
911  //
912  // Load ntdll.dll.
913  //
914  /*
915  Simple
916  GetModuleHandle( "ntdll.dl" )
917  is not suitable due to security issue (see
918  http://www.microsoft.com/technet/security/advisory/2269637.mspx). We have to specify full
919  path to the library.
920  */
921  __kmp_str_buf_init( & path );
922  path_size = GetSystemDirectory( path.str, path.size );
923  KMP_DEBUG_ASSERT( path_size > 0 );
924  if ( path_size >= path.size ) {
925  //
926  // Buffer is too short. Expand the buffer and try again.
927  //
928  __kmp_str_buf_reserve( & path, path_size );
929  path_size = GetSystemDirectory( path.str, path.size );
930  KMP_DEBUG_ASSERT( path_size > 0 );
931  }; // if
932  if ( path_size > 0 && path_size < path.size ) {
933  //
934  // Now we have system directory name in the buffer.
935  // Append backslash and name of dll to form full path,
936  //
937  path.used = path_size;
938  __kmp_str_buf_print( & path, "\\%s", "ntdll.dll" );
939 
940  //
941  // Now load ntdll using full path.
942  //
943  ntdll = GetModuleHandle( path.str );
944  }
945 
946  KMP_DEBUG_ASSERT( ntdll != NULL );
947  if ( ntdll != NULL ) {
948  NtQuerySystemInformation = (NtQuerySystemInformation_t) GetProcAddress( ntdll, "NtQuerySystemInformation" );
949  }
950  KMP_DEBUG_ASSERT( NtQuerySystemInformation != NULL );
951 
952 #if KMP_GROUP_AFFINITY
953  //
954  // Load kernel32.dll.
955  // Same caveat - must use full system path name.
956  //
957  if ( path_size > 0 && path_size < path.size ) {
958  //
959  // Truncate the buffer back to just the system path length,
960  // discarding "\\ntdll.dll", and replacing it with "kernel32.dll".
961  //
962  path.used = path_size;
963  __kmp_str_buf_print( & path, "\\%s", "kernel32.dll" );
964 
965  //
966  // Load kernel32.dll using full path.
967  //
968  kernel32 = GetModuleHandle( path.str );
969  KA_TRACE( 10, ("__kmp_runtime_initialize: kernel32.dll = %s\n", path.str ) );
970 
971  //
972  // Load the function pointers to kernel32.dll routines
973  // that may or may not exist on this system.
974  //
975  if ( kernel32 != NULL ) {
976  __kmp_GetActiveProcessorCount = (kmp_GetActiveProcessorCount_t) GetProcAddress( kernel32, "GetActiveProcessorCount" );
977  __kmp_GetActiveProcessorGroupCount = (kmp_GetActiveProcessorGroupCount_t) GetProcAddress( kernel32, "GetActiveProcessorGroupCount" );
978  __kmp_GetThreadGroupAffinity = (kmp_GetThreadGroupAffinity_t) GetProcAddress( kernel32, "GetThreadGroupAffinity" );
979  __kmp_SetThreadGroupAffinity = (kmp_SetThreadGroupAffinity_t) GetProcAddress( kernel32, "SetThreadGroupAffinity" );
980 
981  KA_TRACE( 10, ("__kmp_runtime_initialize: __kmp_GetActiveProcessorCount = %p\n", __kmp_GetActiveProcessorCount ) );
982  KA_TRACE( 10, ("__kmp_runtime_initialize: __kmp_GetActiveProcessorGroupCount = %p\n", __kmp_GetActiveProcessorGroupCount ) );
983  KA_TRACE( 10, ("__kmp_runtime_initialize:__kmp_GetThreadGroupAffinity = %p\n", __kmp_GetThreadGroupAffinity ) );
984  KA_TRACE( 10, ("__kmp_runtime_initialize: __kmp_SetThreadGroupAffinity = %p\n", __kmp_SetThreadGroupAffinity ) );
985  KA_TRACE( 10, ("__kmp_runtime_initialize: sizeof(kmp_affin_mask_t) = %d\n", sizeof(kmp_affin_mask_t) ) );
986 
987  //
988  // See if group affinity is supported on this system.
989  // If so, calculate the #groups and #procs.
990  //
991  // Group affinity was introduced with Windows* 7 OS and
992  // Windows* Server 2008 R2 OS.
993  //
994  if ( ( __kmp_GetActiveProcessorCount != NULL )
995  && ( __kmp_GetActiveProcessorGroupCount != NULL )
996  && ( __kmp_GetThreadGroupAffinity != NULL )
997  && ( __kmp_SetThreadGroupAffinity != NULL )
998  && ( ( __kmp_num_proc_groups
999  = __kmp_GetActiveProcessorGroupCount() ) > 1 ) ) {
1000  //
1001  // Calculate the total number of active OS procs.
1002  //
1003  int i;
1004 
1005  KA_TRACE( 10, ("__kmp_runtime_initialize: %d processor groups detected\n", __kmp_num_proc_groups ) );
1006 
1007  __kmp_xproc = 0;
1008 
1009  for ( i = 0; i < __kmp_num_proc_groups; i++ ) {
1010  DWORD size = __kmp_GetActiveProcessorCount( i );
1011  __kmp_xproc += size;
1012  KA_TRACE( 10, ("__kmp_runtime_initialize: proc group %d size = %d\n", i, size ) );
1013  }
1014  }
1015  else {
1016  KA_TRACE( 10, ("__kmp_runtime_initialize: %d processor groups detected\n", __kmp_num_proc_groups ) );
1017  }
1018  }
1019  }
1020  if ( __kmp_num_proc_groups <= 1 ) {
1021  GetSystemInfo( & info );
1022  __kmp_xproc = info.dwNumberOfProcessors;
1023  }
1024 #else
1025  GetSystemInfo( & info );
1026  __kmp_xproc = info.dwNumberOfProcessors;
1027 #endif /* KMP_GROUP_AFFINITY */
1028 
1029  //
1030  // If the OS said there were 0 procs, take a guess and use a value of 2.
1031  // This is done for Linux* OS, also. Do we need error / warning?
1032  //
1033  if ( __kmp_xproc <= 0 ) {
1034  __kmp_xproc = 2;
1035  }
1036 
1037  KA_TRACE( 5, ("__kmp_runtime_initialize: total processors = %d\n", __kmp_xproc) );
1038 
1039  __kmp_str_buf_free( & path );
1040 
1041 #if USE_ITT_BUILD
1042  __kmp_itt_initialize();
1043 #endif /* USE_ITT_BUILD */
1044 
1045  __kmp_init_runtime = TRUE;
1046 } // __kmp_runtime_initialize
1047 
1048 void
1049 __kmp_runtime_destroy( void )
1050 {
1051  if ( ! __kmp_init_runtime ) {
1052  return;
1053  }
1054 
1055 #if USE_ITT_BUILD
1056  __kmp_itt_destroy();
1057 #endif /* USE_ITT_BUILD */
1058 
1059  /* we can't DeleteCriticalsection( & __kmp_win32_section ); */
1060  /* due to the KX_TRACE() commands */
1061  KA_TRACE( 40, ("__kmp_runtime_destroy\n" ));
1062 
1063  if( __kmp_gtid_threadprivate_key ) {
1064  TlsFree( __kmp_gtid_threadprivate_key );
1065  __kmp_gtid_threadprivate_key = 0;
1066  }
1067 
1068  __kmp_affinity_uninitialize();
1069  DeleteCriticalSection( & __kmp_win32_section );
1070 
1071  ntdll = NULL;
1072  NtQuerySystemInformation = NULL;
1073 
1074 #if KMP_ARCH_X86_64
1075  kernel32 = NULL;
1076  __kmp_GetActiveProcessorCount = NULL;
1077  __kmp_GetActiveProcessorGroupCount = NULL;
1078  __kmp_GetThreadGroupAffinity = NULL;
1079  __kmp_SetThreadGroupAffinity = NULL;
1080 #endif // KMP_ARCH_X86_64
1081 
1082  __kmp_init_runtime = FALSE;
1083 }
1084 
1085 
1086 void
1087 __kmp_terminate_thread( int gtid )
1088 {
1089  kmp_info_t *th = __kmp_threads[ gtid ];
1090 
1091  if( !th ) return;
1092 
1093  KA_TRACE( 10, ("__kmp_terminate_thread: kill (%d)\n", gtid ) );
1094 
1095  if (TerminateThread( th->th.th_info.ds.ds_thread, (DWORD) -1) == FALSE) {
1096  /* It's OK, the thread may have exited already */
1097  }
1098  __kmp_free_handle( th->th.th_info.ds.ds_thread );
1099 }
1100 
1101 /* ------------------------------------------------------------------------ */
1102 /* ------------------------------------------------------------------------ */
1103 
1104 void
1105 __kmp_clear_system_time( void )
1106 {
1107  BOOL status;
1108  LARGE_INTEGER time;
1109  status = QueryPerformanceCounter( & time );
1110  __kmp_win32_time = (kmp_int64) time.QuadPart;
1111 }
1112 
1113 void
1114 __kmp_initialize_system_tick( void )
1115 {
1116  {
1117  BOOL status;
1118  LARGE_INTEGER freq;
1119 
1120  status = QueryPerformanceFrequency( & freq );
1121  if (! status) {
1122  DWORD error = GetLastError();
1123  __kmp_msg(
1124  kmp_ms_fatal,
1125  KMP_MSG( FunctionError, "QueryPerformanceFrequency()" ),
1126  KMP_ERR( error ),
1127  __kmp_msg_null
1128  );
1129 
1130  }
1131  else {
1132  __kmp_win32_tick = ((double) 1.0) / (double) freq.QuadPart;
1133  }
1134  }
1135 }
1136 
1137 /* Calculate the elapsed wall clock time for the user */
1138 
1139 void
1140 __kmp_elapsed( double *t )
1141 {
1142  BOOL status;
1143  LARGE_INTEGER now;
1144  status = QueryPerformanceCounter( & now );
1145  *t = ((double) now.QuadPart) * __kmp_win32_tick;
1146 }
1147 
1148 /* Calculate the elapsed wall clock tick for the user */
1149 
1150 void
1151 __kmp_elapsed_tick( double *t )
1152 {
1153  *t = __kmp_win32_tick;
1154 }
1155 
1156 void
1157 __kmp_read_system_time( double *delta )
1158 {
1159 
1160  if (delta != NULL) {
1161  BOOL status;
1162  LARGE_INTEGER now;
1163 
1164  status = QueryPerformanceCounter( & now );
1165 
1166  *delta = ((double) (((kmp_int64) now.QuadPart) - __kmp_win32_time))
1167  * __kmp_win32_tick;
1168  }
1169 }
1170 
1171 /* ------------------------------------------------------------------------ */
1172 /* ------------------------------------------------------------------------ */
1173 
1174 void * __stdcall
1175 __kmp_launch_worker( void *arg )
1176 {
1177  volatile void *stack_data;
1178  void *exit_val;
1179  void *padding = 0;
1180  kmp_info_t *this_thr = (kmp_info_t *) arg;
1181  int gtid;
1182 
1183  gtid = this_thr->th.th_info.ds.ds_gtid;
1184  __kmp_gtid_set_specific( gtid );
1185 #ifdef KMP_TDATA_GTID
1186  #error "This define causes problems with LoadLibrary() + declspec(thread) " \
1187  "on Windows* OS. See CQ50564, tests kmp_load_library*.c and this MSDN " \
1188  "reference: http://support.microsoft.com/kb/118816"
1189  //__kmp_gtid = gtid;
1190 #endif
1191 
1192 #if USE_ITT_BUILD
1193  __kmp_itt_thread_name( gtid );
1194 #endif /* USE_ITT_BUILD */
1195 
1196  __kmp_affinity_set_init_mask( gtid, FALSE );
1197 
1198 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
1199  //
1200  // Set the FP control regs to be a copy of
1201  // the parallel initialization thread's.
1202  //
1203  __kmp_clear_x87_fpu_status_word();
1204  __kmp_load_x87_fpu_control_word( &__kmp_init_x87_fpu_control_word );
1205  __kmp_load_mxcsr( &__kmp_init_mxcsr );
1206 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
1207 
1208  if ( __kmp_stkoffset > 0 && gtid > 0 ) {
1209  padding = KMP_ALLOCA( gtid * __kmp_stkoffset );
1210  }
1211 
1212  KMP_FSYNC_RELEASING( &this_thr -> th.th_info.ds.ds_alive );
1213  this_thr -> th.th_info.ds.ds_thread_id = GetCurrentThreadId();
1214  TCW_4( this_thr -> th.th_info.ds.ds_alive, TRUE );
1215 
1216  if ( TCR_4(__kmp_gtid_mode) < 2 ) { // check stack only if it is used to get gtid
1217  TCW_PTR(this_thr->th.th_info.ds.ds_stackbase, &stack_data);
1218  KMP_ASSERT( this_thr -> th.th_info.ds.ds_stackgrow == FALSE );
1219  __kmp_check_stack_overlap( this_thr );
1220  }
1221  KMP_MB();
1222  exit_val = __kmp_launch_thread( this_thr );
1223  KMP_FSYNC_RELEASING( &this_thr -> th.th_info.ds.ds_alive );
1224  TCW_4( this_thr -> th.th_info.ds.ds_alive, FALSE );
1225  KMP_MB();
1226  return exit_val;
1227 }
1228 
1229 
1230 /* The monitor thread controls all of the threads in the complex */
1231 
1232 void * __stdcall
1233 __kmp_launch_monitor( void *arg )
1234 {
1235  DWORD wait_status;
1236  kmp_thread_t monitor;
1237  int status;
1238  int interval;
1239  kmp_info_t *this_thr = (kmp_info_t *) arg;
1240 
1241  KMP_DEBUG_ASSERT(__kmp_init_monitor);
1242  TCW_4( __kmp_init_monitor, 2 ); // AC: Signal the library that monitor has started
1243  // TODO: hide "2" in enum (like {true,false,started})
1244  this_thr -> th.th_info.ds.ds_thread_id = GetCurrentThreadId();
1245  TCW_4( this_thr -> th.th_info.ds.ds_alive, TRUE );
1246 
1247  KMP_MB(); /* Flush all pending memory write invalidates. */
1248  KA_TRACE( 10, ("__kmp_launch_monitor: launched\n" ) );
1249 
1250  monitor = GetCurrentThread();
1251 
1252  /* set thread priority */
1253  status = SetThreadPriority( monitor, THREAD_PRIORITY_HIGHEST );
1254  if (! status) {
1255  DWORD error = GetLastError();
1256  __kmp_msg(
1257  kmp_ms_fatal,
1258  KMP_MSG( CantSetThreadPriority ),
1259  KMP_ERR( error ),
1260  __kmp_msg_null
1261  );
1262  }
1263 
1264  /* register us as monitor */
1265  __kmp_gtid_set_specific( KMP_GTID_MONITOR );
1266 #ifdef KMP_TDATA_GTID
1267  #error "This define causes problems with LoadLibrary() + declspec(thread) " \
1268  "on Windows* OS. See CQ50564, tests kmp_load_library*.c and this MSDN " \
1269  "reference: http://support.microsoft.com/kb/118816"
1270  //__kmp_gtid = KMP_GTID_MONITOR;
1271 #endif
1272 
1273 #if USE_ITT_BUILD
1274  __kmp_itt_thread_ignore(); // Instruct Intel(R) Threading Tools to ignore monitor thread.
1275 #endif /* USE_ITT_BUILD */
1276 
1277  KMP_MB(); /* Flush all pending memory write invalidates. */
1278 
1279  interval = ( 1000 / __kmp_monitor_wakeups ); /* in milliseconds */
1280 
1281  while (! TCR_4(__kmp_global.g.g_done)) {
1282  /* This thread monitors the state of the system */
1283 
1284  KA_TRACE( 15, ( "__kmp_launch_monitor: update\n" ) );
1285 
1286  wait_status = WaitForSingleObject( __kmp_monitor_ev, interval );
1287 
1288  if (wait_status == WAIT_TIMEOUT) {
1289  TCW_4( __kmp_global.g.g_time.dt.t_value,
1290  TCR_4( __kmp_global.g.g_time.dt.t_value ) + 1 );
1291  }
1292 
1293  KMP_MB(); /* Flush all pending memory write invalidates. */
1294  }
1295 
1296  KA_TRACE( 10, ("__kmp_launch_monitor: finished\n" ) );
1297 
1298  status = SetThreadPriority( monitor, THREAD_PRIORITY_NORMAL );
1299  if (! status) {
1300  DWORD error = GetLastError();
1301  __kmp_msg(
1302  kmp_ms_fatal,
1303  KMP_MSG( CantSetThreadPriority ),
1304  KMP_ERR( error ),
1305  __kmp_msg_null
1306  );
1307  }
1308 
1309  if (__kmp_global.g.g_abort != 0) {
1310  /* now we need to terminate the worker threads */
1311  /* the value of t_abort is the signal we caught */
1312 
1313  int gtid;
1314 
1315  KA_TRACE( 10, ("__kmp_launch_monitor: terminate sig=%d\n", (__kmp_global.g.g_abort) ) );
1316 
1317  /* terminate the OpenMP worker threads */
1318  /* TODO this is not valid for sibling threads!!
1319  * the uber master might not be 0 anymore.. */
1320  for (gtid = 1; gtid < __kmp_threads_capacity; ++gtid)
1321  __kmp_terminate_thread( gtid );
1322 
1323  __kmp_cleanup();
1324 
1325  Sleep( 0 );
1326 
1327  KA_TRACE( 10, ("__kmp_launch_monitor: raise sig=%d\n", (__kmp_global.g.g_abort) ) );
1328 
1329  if (__kmp_global.g.g_abort > 0) {
1330  raise( __kmp_global.g.g_abort );
1331  }
1332  }
1333 
1334  TCW_4( this_thr -> th.th_info.ds.ds_alive, FALSE );
1335 
1336  KMP_MB();
1337  return arg;
1338 }
1339 
1340 void
1341 __kmp_create_worker( int gtid, kmp_info_t *th, size_t stack_size )
1342 {
1343  kmp_thread_t handle;
1344  DWORD idThread;
1345 
1346  KA_TRACE( 10, ("__kmp_create_worker: try to create thread (%d)\n", gtid ) );
1347 
1348  th->th.th_info.ds.ds_gtid = gtid;
1349 
1350  if ( KMP_UBER_GTID(gtid) ) {
1351  int stack_data;
1352 
1353  /* TODO: GetCurrentThread() returns a pseudo-handle that is unsuitable for other threads to use.
1354  Is it appropriate to just use GetCurrentThread? When should we close this handle? When
1355  unregistering the root?
1356  */
1357  {
1358  BOOL rc;
1359  rc = DuplicateHandle(
1360  GetCurrentProcess(),
1361  GetCurrentThread(),
1362  GetCurrentProcess(),
1363  &th->th.th_info.ds.ds_thread,
1364  0,
1365  FALSE,
1366  DUPLICATE_SAME_ACCESS
1367  );
1368  KMP_ASSERT( rc );
1369  KA_TRACE( 10, (" __kmp_create_worker: ROOT Handle duplicated, th = %p, handle = %" KMP_UINTPTR_SPEC "\n",
1370  (LPVOID)th,
1371  th->th.th_info.ds.ds_thread ) );
1372  th->th.th_info.ds.ds_thread_id = GetCurrentThreadId();
1373  }
1374  if ( TCR_4(__kmp_gtid_mode) < 2 ) { // check stack only if it is used to get gtid
1375  /* we will dynamically update the stack range if gtid_mode == 1 */
1376  TCW_PTR(th->th.th_info.ds.ds_stackbase, &stack_data);
1377  TCW_PTR(th->th.th_info.ds.ds_stacksize, 0);
1378  TCW_4(th->th.th_info.ds.ds_stackgrow, TRUE);
1379  __kmp_check_stack_overlap( th );
1380  }
1381  }
1382  else {
1383  KMP_MB(); /* Flush all pending memory write invalidates. */
1384 
1385  /* Set stack size for this thread now. */
1386  KA_TRACE( 10, ( "__kmp_create_worker: stack_size = %" KMP_SIZE_T_SPEC
1387  " bytes\n", stack_size ) );
1388 
1389  stack_size += gtid * __kmp_stkoffset;
1390 
1391  TCW_PTR(th->th.th_info.ds.ds_stacksize, stack_size);
1392  TCW_4(th->th.th_info.ds.ds_stackgrow, FALSE);
1393 
1394  KA_TRACE( 10, ( "__kmp_create_worker: (before) stack_size = %"
1395  KMP_SIZE_T_SPEC
1396  " bytes, &__kmp_launch_worker = %p, th = %p, "
1397  "&idThread = %p\n",
1398  (SIZE_T) stack_size,
1399  (LPTHREAD_START_ROUTINE) & __kmp_launch_worker,
1400  (LPVOID) th, &idThread ) );
1401 
1402  {
1403  handle = CreateThread( NULL, (SIZE_T) stack_size,
1404  (LPTHREAD_START_ROUTINE) __kmp_launch_worker,
1405  (LPVOID) th, STACK_SIZE_PARAM_IS_A_RESERVATION, &idThread );
1406  }
1407 
1408  KA_TRACE( 10, ( "__kmp_create_worker: (after) stack_size = %"
1409  KMP_SIZE_T_SPEC
1410  " bytes, &__kmp_launch_worker = %p, th = %p, "
1411  "idThread = %u, handle = %" KMP_UINTPTR_SPEC "\n",
1412  (SIZE_T) stack_size,
1413  (LPTHREAD_START_ROUTINE) & __kmp_launch_worker,
1414  (LPVOID) th, idThread, handle ) );
1415 
1416  {
1417  if ( handle == 0 ) {
1418  DWORD error = GetLastError();
1419  __kmp_msg(
1420  kmp_ms_fatal,
1421  KMP_MSG( CantCreateThread ),
1422  KMP_ERR( error ),
1423  __kmp_msg_null
1424  );
1425  } else {
1426  th->th.th_info.ds.ds_thread = handle;
1427  }
1428  }
1429  KMP_MB(); /* Flush all pending memory write invalidates. */
1430  }
1431 
1432  KA_TRACE( 10, ("__kmp_create_worker: done creating thread (%d)\n", gtid ) );
1433 }
1434 
1435 int
1436 __kmp_still_running(kmp_info_t *th) {
1437  return (WAIT_TIMEOUT == WaitForSingleObject( th->th.th_info.ds.ds_thread, 0));
1438 }
1439 
1440 void
1441 __kmp_create_monitor( kmp_info_t *th )
1442 {
1443  kmp_thread_t handle;
1444  DWORD idThread;
1445  int ideal, new_ideal;
1446  int caller_gtid = __kmp_get_gtid();
1447 
1448  KA_TRACE( 10, ("__kmp_create_monitor: try to create monitor\n" ) );
1449 
1450  KMP_MB(); /* Flush all pending memory write invalidates. */
1451 
1452  __kmp_monitor_ev = CreateEvent( NULL, TRUE, FALSE, NULL );
1453  if ( __kmp_monitor_ev == NULL ) {
1454  DWORD error = GetLastError();
1455  __kmp_msg(
1456  kmp_ms_fatal,
1457  KMP_MSG( CantCreateEvent ),
1458  KMP_ERR( error ),
1459  __kmp_msg_null
1460  );
1461  }; // if
1462 #if USE_ITT_BUILD
1463  __kmp_itt_system_object_created( __kmp_monitor_ev, "Event" );
1464 #endif /* USE_ITT_BUILD */
1465 
1466  th->th.th_info.ds.ds_tid = KMP_GTID_MONITOR;
1467  th->th.th_info.ds.ds_gtid = KMP_GTID_MONITOR;
1468 
1469  // FIXME - on Windows* OS, if __kmp_monitor_stksize = 0, figure out how
1470  // to automatically expand stacksize based on CreateThread error code.
1471  if ( __kmp_monitor_stksize == 0 ) {
1472  __kmp_monitor_stksize = KMP_DEFAULT_MONITOR_STKSIZE;
1473  }
1474  if ( __kmp_monitor_stksize < __kmp_sys_min_stksize ) {
1475  __kmp_monitor_stksize = __kmp_sys_min_stksize;
1476  }
1477 
1478  KA_TRACE( 10, ("__kmp_create_monitor: requested stacksize = %d bytes\n",
1479  (int) __kmp_monitor_stksize ) );
1480 
1481  TCW_4( __kmp_global.g.g_time.dt.t_value, 0 );
1482 
1483  handle = CreateThread( NULL, (SIZE_T) __kmp_monitor_stksize,
1484  (LPTHREAD_START_ROUTINE) __kmp_launch_monitor,
1485  (LPVOID) th, STACK_SIZE_PARAM_IS_A_RESERVATION, &idThread );
1486  if (handle == 0) {
1487  DWORD error = GetLastError();
1488  __kmp_msg(
1489  kmp_ms_fatal,
1490  KMP_MSG( CantCreateThread ),
1491  KMP_ERR( error ),
1492  __kmp_msg_null
1493  );
1494  }
1495  else
1496  th->th.th_info.ds.ds_thread = handle;
1497 
1498  KMP_MB(); /* Flush all pending memory write invalidates. */
1499 
1500  KA_TRACE( 10, ("__kmp_create_monitor: monitor created %p\n",
1501  (void *) th->th.th_info.ds.ds_thread ) );
1502 }
1503 
1504 /*
1505  Check to see if thread is still alive.
1506 
1507  NOTE: The ExitProcess(code) system call causes all threads to Terminate
1508  with a exit_val = code. Because of this we can not rely on
1509  exit_val having any particular value. So this routine may
1510  return STILL_ALIVE in exit_val even after the thread is dead.
1511 */
1512 
1513 int
1514 __kmp_is_thread_alive( kmp_info_t * th, DWORD *exit_val )
1515 {
1516  DWORD rc;
1517  rc = GetExitCodeThread( th->th.th_info.ds.ds_thread, exit_val );
1518  if ( rc == 0 ) {
1519  DWORD error = GetLastError();
1520  __kmp_msg(
1521  kmp_ms_fatal,
1522  KMP_MSG( FunctionError, "GetExitCodeThread()" ),
1523  KMP_ERR( error ),
1524  __kmp_msg_null
1525  );
1526  }; // if
1527  return ( *exit_val == STILL_ACTIVE );
1528 }
1529 
1530 
1531 void
1532 __kmp_exit_thread(
1533  int exit_status
1534 ) {
1535  ExitThread( exit_status );
1536 } // __kmp_exit_thread
1537 
1538 /*
1539  This is a common part for both __kmp_reap_worker() and __kmp_reap_monitor().
1540 */
1541 static void
1542 __kmp_reap_common( kmp_info_t * th )
1543 {
1544  DWORD exit_val;
1545 
1546  KMP_MB(); /* Flush all pending memory write invalidates. */
1547 
1548  KA_TRACE( 10, ( "__kmp_reap_common: try to reap (%d)\n", th->th.th_info.ds.ds_gtid ) );
1549 
1550  /*
1551  2006-10-19:
1552 
1553  There are two opposite situations:
1554 
1555  1. Windows* OS keep thread alive after it resets ds_alive flag and exits from thread
1556  function. (For example, see C70770/Q394281 "unloading of dll based on OMP is very
1557  slow".)
1558  2. Windows* OS may kill thread before it resets ds_alive flag.
1559 
1560  Right solution seems to be waiting for *either* thread termination *or* ds_alive resetting.
1561 
1562  */
1563 
1564  {
1565  // TODO: This code is very similar to KMP_WAIT_YIELD. Need to generalize KMP_WAIT_YIELD to
1566  // cover this usage also.
1567  void * obj = NULL;
1568  register kmp_uint32 spins;
1569 #if USE_ITT_BUILD
1570  KMP_FSYNC_SPIN_INIT( obj, (void*) & th->th.th_info.ds.ds_alive );
1571 #endif /* USE_ITT_BUILD */
1572  KMP_INIT_YIELD( spins );
1573  do {
1574 #if USE_ITT_BUILD
1575  KMP_FSYNC_SPIN_PREPARE( obj );
1576 #endif /* USE_ITT_BUILD */
1577  __kmp_is_thread_alive( th, &exit_val );
1578  KMP_YIELD( TCR_4(__kmp_nth) > __kmp_avail_proc );
1579  KMP_YIELD_SPIN( spins );
1580  } while ( exit_val == STILL_ACTIVE && TCR_4( th->th.th_info.ds.ds_alive ) );
1581 #if USE_ITT_BUILD
1582  if ( exit_val == STILL_ACTIVE ) {
1583  KMP_FSYNC_CANCEL( obj );
1584  } else {
1585  KMP_FSYNC_SPIN_ACQUIRED( obj );
1586  }; // if
1587 #endif /* USE_ITT_BUILD */
1588  }
1589 
1590  __kmp_free_handle( th->th.th_info.ds.ds_thread );
1591 
1592  /*
1593  * NOTE: The ExitProcess(code) system call causes all threads to Terminate
1594  * with a exit_val = code. Because of this we can not rely on
1595  * exit_val having any particular value.
1596  */
1597  if ( exit_val == STILL_ACTIVE ) {
1598  KA_TRACE( 1, ( "__kmp_reap_common: thread still active.\n" ) );
1599  } else if ( (void *) exit_val != (void *) th) {
1600  KA_TRACE( 1, ( "__kmp_reap_common: ExitProcess / TerminateThread used?\n" ) );
1601  }; // if
1602 
1603  KA_TRACE( 10,
1604  (
1605  "__kmp_reap_common: done reaping (%d), handle = %" KMP_UINTPTR_SPEC "\n",
1606  th->th.th_info.ds.ds_gtid,
1607  th->th.th_info.ds.ds_thread
1608  )
1609  );
1610 
1611  th->th.th_info.ds.ds_thread = 0;
1612  th->th.th_info.ds.ds_tid = KMP_GTID_DNE;
1613  th->th.th_info.ds.ds_gtid = KMP_GTID_DNE;
1614  th->th.th_info.ds.ds_thread_id = 0;
1615 
1616  KMP_MB(); /* Flush all pending memory write invalidates. */
1617 }
1618 
1619 void
1620 __kmp_reap_monitor( kmp_info_t *th )
1621 {
1622  int status;
1623 
1624  KA_TRACE( 10, ("__kmp_reap_monitor: try to reap %p\n",
1625  (void *) th->th.th_info.ds.ds_thread ) );
1626 
1627  // If monitor has been created, its tid and gtid should be KMP_GTID_MONITOR.
1628  // If both tid and gtid are 0, it means the monitor did not ever start.
1629  // If both tid and gtid are KMP_GTID_DNE, the monitor has been shut down.
1630  KMP_DEBUG_ASSERT( th->th.th_info.ds.ds_tid == th->th.th_info.ds.ds_gtid );
1631  if ( th->th.th_info.ds.ds_gtid != KMP_GTID_MONITOR ) {
1632  return;
1633  }; // if
1634 
1635  KMP_MB(); /* Flush all pending memory write invalidates. */
1636 
1637  status = SetEvent( __kmp_monitor_ev );
1638  if ( status == FALSE ) {
1639  DWORD error = GetLastError();
1640  __kmp_msg(
1641  kmp_ms_fatal,
1642  KMP_MSG( CantSetEvent ),
1643  KMP_ERR( error ),
1644  __kmp_msg_null
1645  );
1646  }
1647  KA_TRACE( 10, ( "__kmp_reap_monitor: reaping thread (%d)\n", th->th.th_info.ds.ds_gtid ) );
1648  __kmp_reap_common( th );
1649 
1650  __kmp_free_handle( __kmp_monitor_ev );
1651 
1652  KMP_MB(); /* Flush all pending memory write invalidates. */
1653 }
1654 
1655 void
1656 __kmp_reap_worker( kmp_info_t * th )
1657 {
1658  KA_TRACE( 10, ( "__kmp_reap_worker: reaping thread (%d)\n", th->th.th_info.ds.ds_gtid ) );
1659  __kmp_reap_common( th );
1660 }
1661 
1662 /* ------------------------------------------------------------------------ */
1663 /* ------------------------------------------------------------------------ */
1664 
1665 #if KMP_HANDLE_SIGNALS
1666 
1667 
1668 static void
1669 __kmp_team_handler( int signo )
1670 {
1671  if ( __kmp_global.g.g_abort == 0 ) {
1672  // Stage 1 signal handler, let's shut down all of the threads.
1673  if ( __kmp_debug_buf ) {
1674  __kmp_dump_debug_buffer();
1675  }; // if
1676  KMP_MB(); // Flush all pending memory write invalidates.
1677  TCW_4( __kmp_global.g.g_abort, signo );
1678  KMP_MB(); // Flush all pending memory write invalidates.
1679  TCW_4( __kmp_global.g.g_done, TRUE );
1680  KMP_MB(); // Flush all pending memory write invalidates.
1681  }
1682 } // __kmp_team_handler
1683 
1684 
1685 
1686 static
1687 sig_func_t __kmp_signal( int signum, sig_func_t handler ) {
1688  sig_func_t old = signal( signum, handler );
1689  if ( old == SIG_ERR ) {
1690  int error = errno;
1691  __kmp_msg( kmp_ms_fatal, KMP_MSG( FunctionError, "signal" ), KMP_ERR( error ), __kmp_msg_null );
1692  }; // if
1693  return old;
1694 }
1695 
1696 static void
1697 __kmp_install_one_handler(
1698  int sig,
1699  sig_func_t handler,
1700  int parallel_init
1701 ) {
1702  sig_func_t old;
1703  KMP_MB(); /* Flush all pending memory write invalidates. */
1704  KB_TRACE( 60, ("__kmp_install_one_handler: called: sig=%d\n", sig ) );
1705  if ( parallel_init ) {
1706  old = __kmp_signal( sig, handler );
1707  // SIG_DFL on Windows* OS in NULL or 0.
1708  if ( old == __kmp_sighldrs[ sig ] ) {
1709  __kmp_siginstalled[ sig ] = 1;
1710  } else {
1711  // Restore/keep user's handler if one previously installed.
1712  old = __kmp_signal( sig, old );
1713  }; // if
1714  } else {
1715  // Save initial/system signal handlers to see if user handlers installed.
1716  // 2009-09-23: It is a dead code. On Windows* OS __kmp_install_signals called once with
1717  // parallel_init == TRUE.
1718  old = __kmp_signal( sig, SIG_DFL );
1719  __kmp_sighldrs[ sig ] = old;
1720  __kmp_signal( sig, old );
1721  }; // if
1722  KMP_MB(); /* Flush all pending memory write invalidates. */
1723 } // __kmp_install_one_handler
1724 
1725 static void
1726 __kmp_remove_one_handler( int sig ) {
1727  if ( __kmp_siginstalled[ sig ] ) {
1728  sig_func_t old;
1729  KMP_MB(); // Flush all pending memory write invalidates.
1730  KB_TRACE( 60, ( "__kmp_remove_one_handler: called: sig=%d\n", sig ) );
1731  old = __kmp_signal( sig, __kmp_sighldrs[ sig ] );
1732  if ( old != __kmp_team_handler ) {
1733  KB_TRACE( 10, ( "__kmp_remove_one_handler: oops, not our handler, restoring: sig=%d\n", sig ) );
1734  old = __kmp_signal( sig, old );
1735  }; // if
1736  __kmp_sighldrs[ sig ] = NULL;
1737  __kmp_siginstalled[ sig ] = 0;
1738  KMP_MB(); // Flush all pending memory write invalidates.
1739  }; // if
1740 } // __kmp_remove_one_handler
1741 
1742 
1743 void
1744 __kmp_install_signals( int parallel_init )
1745 {
1746  KB_TRACE( 10, ( "__kmp_install_signals: called\n" ) );
1747  if ( ! __kmp_handle_signals ) {
1748  KB_TRACE( 10, ( "__kmp_install_signals: KMP_HANDLE_SIGNALS is false - handlers not installed\n" ) );
1749  return;
1750  }; // if
1751  __kmp_install_one_handler( SIGINT, __kmp_team_handler, parallel_init );
1752  __kmp_install_one_handler( SIGILL, __kmp_team_handler, parallel_init );
1753  __kmp_install_one_handler( SIGABRT, __kmp_team_handler, parallel_init );
1754  __kmp_install_one_handler( SIGFPE, __kmp_team_handler, parallel_init );
1755  __kmp_install_one_handler( SIGSEGV, __kmp_team_handler, parallel_init );
1756  __kmp_install_one_handler( SIGTERM, __kmp_team_handler, parallel_init );
1757 } // __kmp_install_signals
1758 
1759 
1760 void
1761 __kmp_remove_signals( void )
1762 {
1763  int sig;
1764  KB_TRACE( 10, ("__kmp_remove_signals: called\n" ) );
1765  for ( sig = 1; sig < NSIG; ++ sig ) {
1766  __kmp_remove_one_handler( sig );
1767  }; // for sig
1768 } // __kmp_remove_signals
1769 
1770 
1771 #endif // KMP_HANDLE_SIGNALS
1772 
1773 /* Put the thread to sleep for a time period */
1774 void
1775 __kmp_thread_sleep( int millis )
1776 {
1777  DWORD status;
1778 
1779  status = SleepEx( (DWORD) millis, FALSE );
1780  if ( status ) {
1781  DWORD error = GetLastError();
1782  __kmp_msg(
1783  kmp_ms_fatal,
1784  KMP_MSG( FunctionError, "SleepEx()" ),
1785  KMP_ERR( error ),
1786  __kmp_msg_null
1787  );
1788  }
1789 }
1790 
1791 /* Determine whether the given address is mapped into the current address space. */
1792 int
1793 __kmp_is_address_mapped( void * addr )
1794 {
1795  DWORD status;
1796  MEMORY_BASIC_INFORMATION lpBuffer;
1797  SIZE_T dwLength;
1798 
1799  dwLength = sizeof(MEMORY_BASIC_INFORMATION);
1800 
1801  status = VirtualQuery( addr, &lpBuffer, dwLength );
1802 
1803  return !((( lpBuffer.State == MEM_RESERVE) || ( lpBuffer.State == MEM_FREE )) ||
1804  (( lpBuffer.Protect == PAGE_NOACCESS ) || ( lpBuffer.Protect == PAGE_EXECUTE )));
1805 }
1806 
1807 kmp_uint64
1808 __kmp_hardware_timestamp(void)
1809 {
1810  kmp_uint64 r = 0;
1811 
1812  QueryPerformanceCounter((LARGE_INTEGER*) &r);
1813  return r;
1814 }
1815 
1816 /* Free handle and check the error code */
1817 void
1818 __kmp_free_handle( kmp_thread_t tHandle )
1819 {
1820 /* called with parameter type HANDLE also, thus suppose kmp_thread_t defined as HANDLE */
1821  BOOL rc;
1822  rc = CloseHandle( tHandle );
1823  if ( !rc ) {
1824  DWORD error = GetLastError();
1825  __kmp_msg(
1826  kmp_ms_fatal,
1827  KMP_MSG( CantCloseHandle ),
1828  KMP_ERR( error ),
1829  __kmp_msg_null
1830  );
1831  }
1832 }
1833 
1834 int
1835 __kmp_get_load_balance( int max ) {
1836 
1837  static ULONG glb_buff_size = 100 * 1024;
1838 
1839  static int glb_running_threads = 0; /* Saved count of the running threads for the thread balance algortihm */
1840  static double glb_call_time = 0; /* Thread balance algorithm call time */
1841 
1842  int running_threads = 0; // Number of running threads in the system.
1843  NTSTATUS status = 0;
1844  ULONG buff_size = 0;
1845  ULONG info_size = 0;
1846  void * buffer = NULL;
1847  PSYSTEM_PROCESS_INFORMATION spi = NULL;
1848  int first_time = 1;
1849 
1850  double call_time = 0.0; //start, finish;
1851 
1852  __kmp_elapsed( & call_time );
1853 
1854  if ( glb_call_time &&
1855  ( call_time - glb_call_time < __kmp_load_balance_interval ) ) {
1856  running_threads = glb_running_threads;
1857  goto finish;
1858  }
1859  glb_call_time = call_time;
1860 
1861  // Do not spend time on running algorithm if we have a permanent error.
1862  if ( NtQuerySystemInformation == NULL ) {
1863  running_threads = -1;
1864  goto finish;
1865  }; // if
1866 
1867  if ( max <= 0 ) {
1868  max = INT_MAX;
1869  }; // if
1870 
1871  do {
1872 
1873  if ( first_time ) {
1874  buff_size = glb_buff_size;
1875  } else {
1876  buff_size = 2 * buff_size;
1877  }
1878 
1879  buffer = KMP_INTERNAL_REALLOC( buffer, buff_size );
1880  if ( buffer == NULL ) {
1881  running_threads = -1;
1882  goto finish;
1883  }; // if
1884  status = NtQuerySystemInformation( SystemProcessInformation, buffer, buff_size, & info_size );
1885  first_time = 0;
1886 
1887  } while ( status == STATUS_INFO_LENGTH_MISMATCH );
1888  glb_buff_size = buff_size;
1889 
1890  #define CHECK( cond ) \
1891  { \
1892  KMP_DEBUG_ASSERT( cond ); \
1893  if ( ! ( cond ) ) { \
1894  running_threads = -1; \
1895  goto finish; \
1896  } \
1897  }
1898 
1899  CHECK( buff_size >= info_size );
1900  spi = PSYSTEM_PROCESS_INFORMATION( buffer );
1901  for ( ; ; ) {
1902  ptrdiff_t offset = uintptr_t( spi ) - uintptr_t( buffer );
1903  CHECK( 0 <= offset && offset + sizeof( SYSTEM_PROCESS_INFORMATION ) < info_size );
1904  HANDLE pid = spi->ProcessId;
1905  ULONG num = spi->NumberOfThreads;
1906  CHECK( num >= 1 );
1907  size_t spi_size = sizeof( SYSTEM_PROCESS_INFORMATION ) + sizeof( SYSTEM_THREAD ) * ( num - 1 );
1908  CHECK( offset + spi_size < info_size ); // Make sure process info record fits the buffer.
1909  if ( spi->NextEntryOffset != 0 ) {
1910  CHECK( spi_size <= spi->NextEntryOffset ); // And do not overlap with the next record.
1911  }; // if
1912  // pid == 0 corresponds to the System Idle Process. It always has running threads
1913  // on all cores. So, we don't consider the running threads of this process.
1914  if ( pid != 0 ) {
1915  for ( int i = 0; i < num; ++ i ) {
1916  THREAD_STATE state = spi->Threads[ i ].State;
1917  // Count threads that have Ready or Running state.
1918  // !!! TODO: Why comment does not match the code???
1919  if ( state == StateRunning ) {
1920  ++ running_threads;
1921  // Stop counting running threads if the number is already greater than
1922  // the number of available cores
1923  if ( running_threads >= max ) {
1924  goto finish;
1925  }
1926  } // if
1927  }; // for i
1928  } // if
1929  if ( spi->NextEntryOffset == 0 ) {
1930  break;
1931  }; // if
1932  spi = PSYSTEM_PROCESS_INFORMATION( uintptr_t( spi ) + spi->NextEntryOffset );
1933  }; // forever
1934 
1935  #undef CHECK
1936 
1937  finish: // Clean up and exit.
1938 
1939  if ( buffer != NULL ) {
1940  KMP_INTERNAL_FREE( buffer );
1941  }; // if
1942 
1943  glb_running_threads = running_threads;
1944 
1945  return running_threads;
1946 
1947 } //__kmp_get_load_balance()
1948