/*
 * z_Windows_NT_util.cpp -- platform specific routines.
 */

//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "kmp.h"
#include "kmp_affinity.h"
#include "kmp_i18n.h"
#include "kmp_io.h"
#include "kmp_itt.h"
#include "kmp_wait_release.h"

/* This code is related to NtQuerySystemInformation() function. This function
   is used in the Load balance algorithm for OMP_DYNAMIC=true to find the
   number of running threads in the system. */

#include <ntsecapi.h> // UNICODE_STRING
#include <ntstatus.h>
#include <psapi.h>
#ifdef _MSC_VER
#pragma comment(lib, "psapi.lib")
#endif

enum SYSTEM_INFORMATION_CLASS {
  SystemProcessInformation = 5
}; // SYSTEM_INFORMATION_CLASS

struct CLIENT_ID {
  HANDLE UniqueProcess;
  HANDLE UniqueThread;
}; // struct CLIENT_ID

enum THREAD_STATE {
  StateInitialized,
  StateReady,
  StateRunning,
  StateStandby,
  StateTerminated,
  StateWait,
  StateTransition,
  StateUnknown
}; // enum THREAD_STATE

struct VM_COUNTERS {
  SIZE_T PeakVirtualSize;
  SIZE_T VirtualSize;
  ULONG PageFaultCount;
  SIZE_T PeakWorkingSetSize;
  SIZE_T WorkingSetSize;
  SIZE_T QuotaPeakPagedPoolUsage;
  SIZE_T QuotaPagedPoolUsage;
  SIZE_T QuotaPeakNonPagedPoolUsage;
  SIZE_T QuotaNonPagedPoolUsage;
  SIZE_T PagefileUsage;
  SIZE_T PeakPagefileUsage;
  SIZE_T PrivatePageCount;
}; // struct VM_COUNTERS

struct SYSTEM_THREAD {
  LARGE_INTEGER KernelTime;
  LARGE_INTEGER UserTime;
  LARGE_INTEGER CreateTime;
  ULONG WaitTime;
  LPVOID StartAddress;
  CLIENT_ID ClientId;
  DWORD Priority;
  LONG BasePriority;
  ULONG ContextSwitchCount;
  THREAD_STATE State;
  ULONG WaitReason;
}; // SYSTEM_THREAD

KMP_BUILD_ASSERT(offsetof(SYSTEM_THREAD, KernelTime) == 0);
#if KMP_ARCH_X86
KMP_BUILD_ASSERT(offsetof(SYSTEM_THREAD, StartAddress) == 28);
KMP_BUILD_ASSERT(offsetof(SYSTEM_THREAD, State) == 52);
#else
KMP_BUILD_ASSERT(offsetof(SYSTEM_THREAD, StartAddress) == 32);
KMP_BUILD_ASSERT(offsetof(SYSTEM_THREAD, State) == 68);
#endif

struct SYSTEM_PROCESS_INFORMATION {
  ULONG NextEntryOffset;
  ULONG NumberOfThreads;
  LARGE_INTEGER Reserved[3];
  LARGE_INTEGER CreateTime;
  LARGE_INTEGER UserTime;
  LARGE_INTEGER KernelTime;
  UNICODE_STRING ImageName;
  DWORD BasePriority;
  HANDLE ProcessId;
  HANDLE ParentProcessId;
  ULONG HandleCount;
  ULONG Reserved2[2];
  VM_COUNTERS VMCounters;
  IO_COUNTERS IOCounters;
  SYSTEM_THREAD Threads[1];
}; // SYSTEM_PROCESS_INFORMATION
typedef SYSTEM_PROCESS_INFORMATION *PSYSTEM_PROCESS_INFORMATION;

KMP_BUILD_ASSERT(offsetof(SYSTEM_PROCESS_INFORMATION, NextEntryOffset) == 0);
KMP_BUILD_ASSERT(offsetof(SYSTEM_PROCESS_INFORMATION, CreateTime) == 32);
KMP_BUILD_ASSERT(offsetof(SYSTEM_PROCESS_INFORMATION, ImageName) == 56);
#if KMP_ARCH_X86
KMP_BUILD_ASSERT(offsetof(SYSTEM_PROCESS_INFORMATION, ProcessId) == 68);
KMP_BUILD_ASSERT(offsetof(SYSTEM_PROCESS_INFORMATION, HandleCount) == 76);
KMP_BUILD_ASSERT(offsetof(SYSTEM_PROCESS_INFORMATION, VMCounters) == 88);
KMP_BUILD_ASSERT(offsetof(SYSTEM_PROCESS_INFORMATION, IOCounters) == 136);
KMP_BUILD_ASSERT(offsetof(SYSTEM_PROCESS_INFORMATION, Threads) == 184);
#else
KMP_BUILD_ASSERT(offsetof(SYSTEM_PROCESS_INFORMATION, ProcessId) == 80);
KMP_BUILD_ASSERT(offsetof(SYSTEM_PROCESS_INFORMATION, HandleCount) == 96);
KMP_BUILD_ASSERT(offsetof(SYSTEM_PROCESS_INFORMATION, VMCounters) == 112);
KMP_BUILD_ASSERT(offsetof(SYSTEM_PROCESS_INFORMATION, IOCounters) == 208);
KMP_BUILD_ASSERT(offsetof(SYSTEM_PROCESS_INFORMATION, Threads) == 256);
#endif

typedef NTSTATUS(NTAPI *NtQuerySystemInformation_t)(SYSTEM_INFORMATION_CLASS,
                                                    PVOID, ULONG, PULONG);
NtQuerySystemInformation_t NtQuerySystemInformation = NULL;

HMODULE ntdll = NULL;

/* End of NtQuerySystemInformation()-related code */

static HMODULE kernel32 = NULL;

#if KMP_HANDLE_SIGNALS
typedef void (*sig_func_t)(int);
static sig_func_t __kmp_sighldrs[NSIG];
static int __kmp_siginstalled[NSIG];
#endif

#if KMP_USE_MONITOR
static HANDLE __kmp_monitor_ev;
#endif
static kmp_int64 __kmp_win32_time;
double __kmp_win32_tick;

int __kmp_init_runtime = FALSE;
CRITICAL_SECTION __kmp_win32_section;

void __kmp_win32_mutex_init(kmp_win32_mutex_t *mx) {
  InitializeCriticalSection(&mx->cs);
#if USE_ITT_BUILD
  __kmp_itt_system_object_created(&mx->cs, "Critical Section");
#endif /* USE_ITT_BUILD */
}

void __kmp_win32_mutex_destroy(kmp_win32_mutex_t *mx) {
  DeleteCriticalSection(&mx->cs);
}

void __kmp_win32_mutex_lock(kmp_win32_mutex_t *mx) {
  EnterCriticalSection(&mx->cs);
}

int __kmp_win32_mutex_trylock(kmp_win32_mutex_t *mx) {
  return TryEnterCriticalSection(&mx->cs);
}

void __kmp_win32_mutex_unlock(kmp_win32_mutex_t *mx) {
  LeaveCriticalSection(&mx->cs);
}

void __kmp_win32_cond_init(kmp_win32_cond_t *cv) {
  cv->waiters_count_ = 0;
  cv->wait_generation_count_ = 0;
  cv->release_count_ = 0;

  /* Initialize the critical section */
  __kmp_win32_mutex_init(&cv->waiters_count_lock_);

  /* Create a manual-reset event. */
  cv->event_ = CreateEvent(NULL, // no security
                           TRUE, // manual-reset
                           FALSE, // non-signaled initially
                           NULL); // unnamed
#if USE_ITT_BUILD
  __kmp_itt_system_object_created(cv->event_, "Event");
#endif /* USE_ITT_BUILD */
}

void __kmp_win32_cond_destroy(kmp_win32_cond_t *cv) {
  __kmp_win32_mutex_destroy(&cv->waiters_count_lock_);
  __kmp_free_handle(cv->event_);
  memset(cv, '\0', sizeof(*cv));
}

/* TODO associate cv with a team instead of a thread so as to optimize
   the case where we wake up a whole team */

template <class C>
static void __kmp_win32_cond_wait(kmp_win32_cond_t *cv, kmp_win32_mutex_t *mx,
                                  kmp_info_t *th, C *flag) {
  int my_generation;
  int last_waiter;

  /* Avoid race conditions */
  __kmp_win32_mutex_lock(&cv->waiters_count_lock_);

  /* Increment count of waiters */
  cv->waiters_count_++;

  /* Store current generation in our activation record. */
  my_generation = cv->wait_generation_count_;

  __kmp_win32_mutex_unlock(&cv->waiters_count_lock_);
  __kmp_win32_mutex_unlock(mx);

  for (;;) {
    int wait_done = 0;
    DWORD res, timeout = 5000; // just tried to quess an appropriate number
    /* Wait until the event is signaled */
    res = WaitForSingleObject(cv->event_, timeout);

    if (res == WAIT_OBJECT_0) {
      // event signaled
      __kmp_win32_mutex_lock(&cv->waiters_count_lock_);
      /* Exit the loop when the <cv->event_> is signaled and there are still
         waiting threads from this <wait_generation> that haven't been released
         from this wait yet. */
      wait_done = (cv->release_count_ > 0) &&
                  (cv->wait_generation_count_ != my_generation);
      __kmp_win32_mutex_unlock(&cv->waiters_count_lock_);
    } else if (res == WAIT_TIMEOUT || res == WAIT_FAILED) {
      // check if the flag and cv counters are in consistent state
      // as MS sent us debug dump whith inconsistent state of data
      __kmp_win32_mutex_lock(mx);
      typename C::flag_t old_f = flag->set_sleeping();
      if (!flag->done_check_val(old_f & ~KMP_BARRIER_SLEEP_STATE)) {
        __kmp_win32_mutex_unlock(mx);
        continue;
      }
      // condition fulfilled, exiting
      flag->unset_sleeping();
      TCW_PTR(th->th.th_sleep_loc, NULL);
      th->th.th_sleep_loc_type = flag_unset;
      KF_TRACE(50, ("__kmp_win32_cond_wait: exiting, condition "
                    "fulfilled: flag's loc(%p): %u\n",
                    flag->get(), (unsigned int)flag->load()));

      __kmp_win32_mutex_lock(&cv->waiters_count_lock_);
      KMP_DEBUG_ASSERT(cv->waiters_count_ > 0);
      cv->release_count_ = cv->waiters_count_;
      cv->wait_generation_count_++;
      wait_done = 1;
      __kmp_win32_mutex_unlock(&cv->waiters_count_lock_);

      __kmp_win32_mutex_unlock(mx);
    }
    /* there used to be a semicolon after the if statement, it looked like a
       bug, so i removed it */
    if (wait_done)
      break;
  }

  __kmp_win32_mutex_lock(mx);
  __kmp_win32_mutex_lock(&cv->waiters_count_lock_);

  cv->waiters_count_--;
  cv->release_count_--;

  last_waiter = (cv->release_count_ == 0);

  __kmp_win32_mutex_unlock(&cv->waiters_count_lock_);

  if (last_waiter) {
    /* We're the last waiter to be notified, so reset the manual event. */
    ResetEvent(cv->event_);
  }
}

void __kmp_win32_cond_broadcast(kmp_win32_cond_t *cv) {
  __kmp_win32_mutex_lock(&cv->waiters_count_lock_);

  if (cv->waiters_count_ > 0) {
    SetEvent(cv->event_);
    /* Release all the threads in this generation. */

    cv->release_count_ = cv->waiters_count_;

    /* Start a new generation. */
    cv->wait_generation_count_++;
  }

  __kmp_win32_mutex_unlock(&cv->waiters_count_lock_);
}

void __kmp_win32_cond_signal(kmp_win32_cond_t *cv) {
  __kmp_win32_cond_broadcast(cv);
}

void __kmp_enable(int new_state) {
  if (__kmp_init_runtime)
    LeaveCriticalSection(&__kmp_win32_section);
}

void __kmp_disable(int *old_state) {
  *old_state = 0;

  if (__kmp_init_runtime)
    EnterCriticalSection(&__kmp_win32_section);
}

void __kmp_suspend_initialize(void) { /* do nothing */
}

void __kmp_suspend_initialize_thread(kmp_info_t *th) {
  int old_value = KMP_ATOMIC_LD_RLX(&th->th.th_suspend_init);
  int new_value = TRUE;
  // Return if already initialized
  if (old_value == new_value)
    return;
  // Wait, then return if being initialized
  if (old_value == -1 ||
      !__kmp_atomic_compare_store(&th->th.th_suspend_init, old_value, -1)) {
    while (KMP_ATOMIC_LD_ACQ(&th->th.th_suspend_init) != new_value) {
      KMP_CPU_PAUSE();
    }
  } else {
    // Claim to be the initializer and do initializations
    __kmp_win32_cond_init(&th->th.th_suspend_cv);
    __kmp_win32_mutex_init(&th->th.th_suspend_mx);
    KMP_ATOMIC_ST_REL(&th->th.th_suspend_init, new_value);
  }
}

void __kmp_suspend_uninitialize_thread(kmp_info_t *th) {
  if (KMP_ATOMIC_LD_ACQ(&th->th.th_suspend_init)) {
    /* this means we have initialize the suspension pthread objects for this
       thread in this instance of the process */
    __kmp_win32_cond_destroy(&th->th.th_suspend_cv);
    __kmp_win32_mutex_destroy(&th->th.th_suspend_mx);
    KMP_ATOMIC_ST_REL(&th->th.th_suspend_init, FALSE);
  }
}

int __kmp_try_suspend_mx(kmp_info_t *th) {
  return __kmp_win32_mutex_trylock(&th->th.th_suspend_mx);
}

void __kmp_lock_suspend_mx(kmp_info_t *th) {
  __kmp_win32_mutex_lock(&th->th.th_suspend_mx);
}

void __kmp_unlock_suspend_mx(kmp_info_t *th) {
  __kmp_win32_mutex_unlock(&th->th.th_suspend_mx);
}

/* This routine puts the calling thread to sleep after setting the
   sleep bit for the indicated flag variable to true. */
template <class C>
static inline void __kmp_suspend_template(int th_gtid, C *flag) {
  kmp_info_t *th = __kmp_threads[th_gtid];
  typename C::flag_t old_spin;

  KF_TRACE(30, ("__kmp_suspend_template: T#%d enter for flag's loc(%p)\n",
                th_gtid, flag->get()));

  __kmp_suspend_initialize_thread(th);
  __kmp_lock_suspend_mx(th);

  KF_TRACE(10, ("__kmp_suspend_template: T#%d setting sleep bit for flag's"
                " loc(%p)\n",
                th_gtid, flag->get()));

  /* TODO: shouldn't this use release semantics to ensure that
     __kmp_suspend_initialize_thread gets called first? */
  old_spin = flag->set_sleeping();
  TCW_PTR(th->th.th_sleep_loc, (void *)flag);
  th->th.th_sleep_loc_type = flag->get_type();
  if (__kmp_dflt_blocktime == KMP_MAX_BLOCKTIME &&
      __kmp_pause_status != kmp_soft_paused) {
    flag->unset_sleeping();
    TCW_PTR(th->th.th_sleep_loc, NULL);
    th->th.th_sleep_loc_type = flag_unset;
    __kmp_unlock_suspend_mx(th);
    return;
  }

  KF_TRACE(5, ("__kmp_suspend_template: T#%d set sleep bit for flag's"
               " loc(%p)==%u\n",
               th_gtid, flag->get(), (unsigned int)flag->load()));

  if (flag->done_check_val(old_spin) || flag->done_check()) {
    flag->unset_sleeping();
    TCW_PTR(th->th.th_sleep_loc, NULL);
    th->th.th_sleep_loc_type = flag_unset;
    KF_TRACE(5, ("__kmp_suspend_template: T#%d false alarm, reset sleep bit "
                 "for flag's loc(%p)\n",
                 th_gtid, flag->get()));
  } else {
#ifdef DEBUG_SUSPEND
    __kmp_suspend_count++;
#endif
    /* Encapsulate in a loop as the documentation states that this may "with
       low probability" return when the condition variable has not been signaled
       or broadcast */
    int deactivated = FALSE;

    while (flag->is_sleeping()) {
      KF_TRACE(15, ("__kmp_suspend_template: T#%d about to perform "
                    "kmp_win32_cond_wait()\n",
                    th_gtid));
      // Mark the thread as no longer active (only in the first iteration of the
      // loop).
      if (!deactivated) {
        th->th.th_active = FALSE;
        if (th->th.th_active_in_pool) {
          th->th.th_active_in_pool = FALSE;
          KMP_ATOMIC_DEC(&__kmp_thread_pool_active_nth);
          KMP_DEBUG_ASSERT(TCR_4(__kmp_thread_pool_active_nth) >= 0);
        }
        deactivated = TRUE;
      }

      KMP_DEBUG_ASSERT(th->th.th_sleep_loc);
      KMP_DEBUG_ASSERT(th->th.th_sleep_loc_type == flag->get_type());

      __kmp_win32_cond_wait(&th->th.th_suspend_cv, &th->th.th_suspend_mx, th,
                            flag);

#ifdef KMP_DEBUG
      if (flag->is_sleeping()) {
        KF_TRACE(100,
                 ("__kmp_suspend_template: T#%d spurious wakeup\n", th_gtid));
      }
#endif /* KMP_DEBUG */

    } // while

    // We may have had the loop variable set before entering the loop body;
    // so we need to reset sleep_loc.
    TCW_PTR(th->th.th_sleep_loc, NULL);
    th->th.th_sleep_loc_type = flag_unset;

    KMP_DEBUG_ASSERT(!flag->is_sleeping());
    KMP_DEBUG_ASSERT(!th->th.th_sleep_loc);

    // Mark the thread as active again (if it was previous marked as inactive)
    if (deactivated) {
      th->th.th_active = TRUE;
      if (TCR_4(th->th.th_in_pool)) {
        KMP_ATOMIC_INC(&__kmp_thread_pool_active_nth);
        th->th.th_active_in_pool = TRUE;
      }
    }
  }

  __kmp_unlock_suspend_mx(th);
  KF_TRACE(30, ("__kmp_suspend_template: T#%d exit\n", th_gtid));
}

template <bool C, bool S>
void __kmp_suspend_32(int th_gtid, kmp_flag_32<C, S> *flag) {
  __kmp_suspend_template(th_gtid, flag);
}
template <bool C, bool S>
void __kmp_suspend_64(int th_gtid, kmp_flag_64<C, S> *flag) {
  __kmp_suspend_template(th_gtid, flag);
}
template <bool C, bool S>
void __kmp_atomic_suspend_64(int th_gtid, kmp_atomic_flag_64<C, S> *flag) {
  __kmp_suspend_template(th_gtid, flag);
}
void __kmp_suspend_oncore(int th_gtid, kmp_flag_oncore *flag) {
  __kmp_suspend_template(th_gtid, flag);
}

template void __kmp_suspend_32<false, false>(int, kmp_flag_32<false, false> *);
template void __kmp_suspend_64<false, true>(int, kmp_flag_64<false, true> *);
template void __kmp_suspend_64<true, false>(int, kmp_flag_64<true, false> *);
template void
__kmp_atomic_suspend_64<false, true>(int, kmp_atomic_flag_64<false, true> *);
template void
__kmp_atomic_suspend_64<true, false>(int, kmp_atomic_flag_64<true, false> *);

/* This routine signals the thread specified by target_gtid to wake up
   after setting the sleep bit indicated by the flag argument to FALSE */
template <class C>
static inline void __kmp_resume_template(int target_gtid, C *flag) {
  kmp_info_t *th = __kmp_threads[target_gtid];

#ifdef KMP_DEBUG
  int gtid = TCR_4(__kmp_init_gtid) ? __kmp_get_gtid() : -1;
#endif

  KF_TRACE(30, ("__kmp_resume_template: T#%d wants to wakeup T#%d enter\n",
                gtid, target_gtid));

  __kmp_suspend_initialize_thread(th);
  __kmp_lock_suspend_mx(th);

  if (!flag || flag != th->th.th_sleep_loc) {
    // coming from __kmp_null_resume_wrapper, or thread is now sleeping on a
    // different location; wake up at new location
    flag = (C *)th->th.th_sleep_loc;
  }

  // First, check if the flag is null or its type has changed. If so, someone
  // else woke it up.
  if (!flag || flag->get_type() != th->th.th_sleep_loc_type) {
    // simply shows what flag was cast to
    KF_TRACE(5, ("__kmp_resume_template: T#%d exiting, thread T#%d already "
                 "awake: flag's loc(%p)\n",
                 gtid, target_gtid, NULL));
    __kmp_unlock_suspend_mx(th);
    return;
  } else {
    if (!flag->is_sleeping()) {
      KF_TRACE(5, ("__kmp_resume_template: T#%d exiting, thread T#%d already "
                   "awake: flag's loc(%p): %u\n",
                   gtid, target_gtid, flag->get(), (unsigned int)flag->load()));
      __kmp_unlock_suspend_mx(th);
      return;
    }
  }
  KMP_DEBUG_ASSERT(flag);
  flag->unset_sleeping();
  TCW_PTR(th->th.th_sleep_loc, NULL);
  th->th.th_sleep_loc_type = flag_unset;

  KF_TRACE(5, ("__kmp_resume_template: T#%d about to wakeup T#%d, reset sleep "
               "bit for flag's loc(%p)\n",
               gtid, target_gtid, flag->get()));

  __kmp_win32_cond_signal(&th->th.th_suspend_cv);
  __kmp_unlock_suspend_mx(th);

  KF_TRACE(30, ("__kmp_resume_template: T#%d exiting after signaling wake up"
                " for T#%d\n",
                gtid, target_gtid));
}

template <bool C, bool S>
void __kmp_resume_32(int target_gtid, kmp_flag_32<C, S> *flag) {
  __kmp_resume_template(target_gtid, flag);
}
template <bool C, bool S>
void __kmp_resume_64(int target_gtid, kmp_flag_64<C, S> *flag) {
  __kmp_resume_template(target_gtid, flag);
}
template <bool C, bool S>
void __kmp_atomic_resume_64(int target_gtid, kmp_atomic_flag_64<C, S> *flag) {
  __kmp_resume_template(target_gtid, flag);
}
void __kmp_resume_oncore(int target_gtid, kmp_flag_oncore *flag) {
  __kmp_resume_template(target_gtid, flag);
}

template void __kmp_resume_32<false, true>(int, kmp_flag_32<false, true> *);
template void __kmp_resume_32<false, false>(int, kmp_flag_32<false, false> *);
template void __kmp_resume_64<false, true>(int, kmp_flag_64<false, true> *);
template void
__kmp_atomic_resume_64<false, true>(int, kmp_atomic_flag_64<false, true> *);

void __kmp_yield() { Sleep(0); }

void __kmp_gtid_set_specific(int gtid) {
  if (__kmp_init_gtid) {
    KA_TRACE(50, ("__kmp_gtid_set_specific: T#%d key:%d\n", gtid,
                  __kmp_gtid_threadprivate_key));
    if (!TlsSetValue(__kmp_gtid_threadprivate_key, (LPVOID)(gtid + 1)))
      KMP_FATAL(TLSSetValueFailed);
  } else {
    KA_TRACE(50, ("__kmp_gtid_set_specific: runtime shutdown, returning\n"));
  }
}

int __kmp_gtid_get_specific() {
  int gtid;
  if (!__kmp_init_gtid) {
    KA_TRACE(50, ("__kmp_gtid_get_specific: runtime shutdown, returning "
                  "KMP_GTID_SHUTDOWN\n"));
    return KMP_GTID_SHUTDOWN;
  }
  gtid = (int)(kmp_intptr_t)TlsGetValue(__kmp_gtid_threadprivate_key);
  if (gtid == 0) {
    gtid = KMP_GTID_DNE;
  } else {
    gtid--;
  }
  KA_TRACE(50, ("__kmp_gtid_get_specific: key:%d gtid:%d\n",
                __kmp_gtid_threadprivate_key, gtid));
  return gtid;
}

void __kmp_affinity_bind_thread(int proc) {
  if (__kmp_num_proc_groups > 1) {
    // Form the GROUP_AFFINITY struct directly, rather than filling
    // out a bit vector and calling __kmp_set_system_affinity().
    GROUP_AFFINITY ga;
    KMP_DEBUG_ASSERT((proc >= 0) && (proc < (__kmp_num_proc_groups * CHAR_BIT *
                                             sizeof(DWORD_PTR))));
    ga.Group = proc / (CHAR_BIT * sizeof(DWORD_PTR));
    ga.Mask = (unsigned long long)1 << (proc % (CHAR_BIT * sizeof(DWORD_PTR)));
    ga.Reserved[0] = ga.Reserved[1] = ga.Reserved[2] = 0;

    KMP_DEBUG_ASSERT(__kmp_SetThreadGroupAffinity != NULL);
    if (__kmp_SetThreadGroupAffinity(GetCurrentThread(), &ga, NULL) == 0) {
      DWORD error = GetLastError();
      if (__kmp_affinity_verbose) { // AC: continue silently if not verbose
        kmp_msg_t err_code = KMP_ERR(error);
        __kmp_msg(kmp_ms_warning, KMP_MSG(CantSetThreadAffMask), err_code,
                  __kmp_msg_null);
        if (__kmp_generate_warnings == kmp_warnings_off) {
          __kmp_str_free(&err_code.str);
        }
      }
    }
  } else {
    kmp_affin_mask_t *mask;
    KMP_CPU_ALLOC_ON_STACK(mask);
    KMP_CPU_ZERO(mask);
    KMP_CPU_SET(proc, mask);
    __kmp_set_system_affinity(mask, TRUE);
    KMP_CPU_FREE_FROM_STACK(mask);
  }
}

void __kmp_affinity_determine_capable(const char *env_var) {
  // All versions of Windows* OS (since Win '95) support
  // SetThreadAffinityMask().

#if KMP_GROUP_AFFINITY
  KMP_AFFINITY_ENABLE(__kmp_num_proc_groups * sizeof(DWORD_PTR));
#else
  KMP_AFFINITY_ENABLE(sizeof(DWORD_PTR));
#endif

  KA_TRACE(10, ("__kmp_affinity_determine_capable: "
                "Windows* OS affinity interface functional (mask size = "
                "%" KMP_SIZE_T_SPEC ").\n",
                __kmp_affin_mask_size));
}

double __kmp_read_cpu_time(void) {
  FILETIME CreationTime, ExitTime, KernelTime, UserTime;
  int status;
  double cpu_time;

  cpu_time = 0;

  status = GetProcessTimes(GetCurrentProcess(), &CreationTime, &ExitTime,
                           &KernelTime, &UserTime);

  if (status) {
    double sec = 0;

    sec += KernelTime.dwHighDateTime;
    sec += UserTime.dwHighDateTime;

    /* Shift left by 32 bits */
    sec *= (double)(1 << 16) * (double)(1 << 16);

    sec += KernelTime.dwLowDateTime;
    sec += UserTime.dwLowDateTime;

    cpu_time += (sec * 100.0) / KMP_NSEC_PER_SEC;
  }

  return cpu_time;
}

int __kmp_read_system_info(struct kmp_sys_info *info) {
  info->maxrss = 0; /* the maximum resident set size utilized (in kilobytes) */
  info->minflt = 0; /* the number of page faults serviced without any I/O */
  info->majflt = 0; /* the number of page faults serviced that required I/O */
  info->nswap = 0; // the number of times a process was "swapped" out of memory
  info->inblock = 0; // the number of times the file system had to perform input
  info->oublock = 0; // number of times the file system had to perform output
  info->nvcsw = 0; /* the number of times a context switch was voluntarily */
  info->nivcsw = 0; /* the number of times a context switch was forced */

  return 1;
}

void __kmp_runtime_initialize(void) {
  SYSTEM_INFO info;
  kmp_str_buf_t path;
  UINT path_size;

  if (__kmp_init_runtime) {
    return;
  }

#if KMP_DYNAMIC_LIB
  /* Pin dynamic library for the lifetime of application */
  {
    // First, turn off error message boxes
    UINT err_mode = SetErrorMode(SEM_FAILCRITICALERRORS);
    HMODULE h;
    BOOL ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
                                     GET_MODULE_HANDLE_EX_FLAG_PIN,
                                 (LPCTSTR)&__kmp_serial_initialize, &h);
    (void)ret;
    KMP_DEBUG_ASSERT2(h && ret, "OpenMP RTL cannot find itself loaded");
    SetErrorMode(err_mode); // Restore error mode
    KA_TRACE(10, ("__kmp_runtime_initialize: dynamic library pinned\n"));
  }
#endif

  InitializeCriticalSection(&__kmp_win32_section);
#if USE_ITT_BUILD
  __kmp_itt_system_object_created(&__kmp_win32_section, "Critical Section");
#endif /* USE_ITT_BUILD */
  __kmp_initialize_system_tick();

#if (KMP_ARCH_X86 || KMP_ARCH_X86_64)
  if (!__kmp_cpuinfo.initialized) {
    __kmp_query_cpuid(&__kmp_cpuinfo);
  }
#endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */

/* Set up minimum number of threads to switch to TLS gtid */
#if KMP_OS_WINDOWS && !KMP_DYNAMIC_LIB
  // Windows* OS, static library.
  /* New thread may use stack space previously used by another thread,
     currently terminated. On Windows* OS, in case of static linking, we do not
     know the moment of thread termination, and our structures (__kmp_threads
     and __kmp_root arrays) are still keep info about dead threads. This leads
     to problem in __kmp_get_global_thread_id() function: it wrongly finds gtid
     (by searching through stack addresses of all known threads) for
     unregistered foreign tread.

     Setting __kmp_tls_gtid_min to 0 workarounds this problem:
     __kmp_get_global_thread_id() does not search through stacks, but get gtid
     from TLS immediately.
      --ln
  */
  __kmp_tls_gtid_min = 0;
#else
  __kmp_tls_gtid_min = KMP_TLS_GTID_MIN;
#endif

  /* for the static library */
  if (!__kmp_gtid_threadprivate_key) {
    __kmp_gtid_threadprivate_key = TlsAlloc();
    if (__kmp_gtid_threadprivate_key == TLS_OUT_OF_INDEXES) {
      KMP_FATAL(TLSOutOfIndexes);
    }
  }

  // Load ntdll.dll.
  /* Simple GetModuleHandle( "ntdll.dl" ) is not suitable due to security issue
     (see http://www.microsoft.com/technet/security/advisory/2269637.mspx). We
     have to specify full path to the library. */
  __kmp_str_buf_init(&path);
  path_size = GetSystemDirectory(path.str, path.size);
  KMP_DEBUG_ASSERT(path_size > 0);
  if (path_size >= path.size) {
    // Buffer is too short.  Expand the buffer and try again.
    __kmp_str_buf_reserve(&path, path_size);
    path_size = GetSystemDirectory(path.str, path.size);
    KMP_DEBUG_ASSERT(path_size > 0);
  }
  if (path_size > 0 && path_size < path.size) {
    // Now we have system directory name in the buffer.
    // Append backslash and name of dll to form full path,
    path.used = path_size;
    __kmp_str_buf_print(&path, "\\%s", "ntdll.dll");

    // Now load ntdll using full path.
    ntdll = GetModuleHandle(path.str);
  }

  KMP_DEBUG_ASSERT(ntdll != NULL);
  if (ntdll != NULL) {
    NtQuerySystemInformation = (NtQuerySystemInformation_t)GetProcAddress(
        ntdll, "NtQuerySystemInformation");
  }
  KMP_DEBUG_ASSERT(NtQuerySystemInformation != NULL);

#if KMP_GROUP_AFFINITY
  // Load kernel32.dll.
  // Same caveat - must use full system path name.
  if (path_size > 0 && path_size < path.size) {
    // Truncate the buffer back to just the system path length,
    // discarding "\\ntdll.dll", and replacing it with "kernel32.dll".
    path.used = path_size;
    __kmp_str_buf_print(&path, "\\%s", "kernel32.dll");

    // Load kernel32.dll using full path.
    kernel32 = GetModuleHandle(path.str);
    KA_TRACE(10, ("__kmp_runtime_initialize: kernel32.dll = %s\n", path.str));

    // Load the function pointers to kernel32.dll routines
    // that may or may not exist on this system.
    if (kernel32 != NULL) {
      __kmp_GetActiveProcessorCount =
          (kmp_GetActiveProcessorCount_t)GetProcAddress(
              kernel32, "GetActiveProcessorCount");
      __kmp_GetActiveProcessorGroupCount =
          (kmp_GetActiveProcessorGroupCount_t)GetProcAddress(
              kernel32, "GetActiveProcessorGroupCount");
      __kmp_GetThreadGroupAffinity =
          (kmp_GetThreadGroupAffinity_t)GetProcAddress(
              kernel32, "GetThreadGroupAffinity");
      __kmp_SetThreadGroupAffinity =
          (kmp_SetThreadGroupAffinity_t)GetProcAddress(
              kernel32, "SetThreadGroupAffinity");

      KA_TRACE(10, ("__kmp_runtime_initialize: __kmp_GetActiveProcessorCount"
                    " = %p\n",
                    __kmp_GetActiveProcessorCount));
      KA_TRACE(10, ("__kmp_runtime_initialize: "
                    "__kmp_GetActiveProcessorGroupCount = %p\n",
                    __kmp_GetActiveProcessorGroupCount));
      KA_TRACE(10, ("__kmp_runtime_initialize:__kmp_GetThreadGroupAffinity"
                    " = %p\n",
                    __kmp_GetThreadGroupAffinity));
      KA_TRACE(10, ("__kmp_runtime_initialize: __kmp_SetThreadGroupAffinity"
                    " = %p\n",
                    __kmp_SetThreadGroupAffinity));
      KA_TRACE(10, ("__kmp_runtime_initialize: sizeof(kmp_affin_mask_t) = %d\n",
                    sizeof(kmp_affin_mask_t)));

      // See if group affinity is supported on this system.
      // If so, calculate the #groups and #procs.
      //
      // Group affinity was introduced with Windows* 7 OS and
      // Windows* Server 2008 R2 OS.
      if ((__kmp_GetActiveProcessorCount != NULL) &&
          (__kmp_GetActiveProcessorGroupCount != NULL) &&
          (__kmp_GetThreadGroupAffinity != NULL) &&
          (__kmp_SetThreadGroupAffinity != NULL) &&
          ((__kmp_num_proc_groups = __kmp_GetActiveProcessorGroupCount()) >
           1)) {
        // Calculate the total number of active OS procs.
        int i;

        KA_TRACE(10, ("__kmp_runtime_initialize: %d processor groups"
                      " detected\n",
                      __kmp_num_proc_groups));

        __kmp_xproc = 0;

        for (i = 0; i < __kmp_num_proc_groups; i++) {
          DWORD size = __kmp_GetActiveProcessorCount(i);
          __kmp_xproc += size;
          KA_TRACE(10, ("__kmp_runtime_initialize: proc group %d size = %d\n",
                        i, size));
        }
      } else {
        KA_TRACE(10, ("__kmp_runtime_initialize: %d processor groups"
                      " detected\n",
                      __kmp_num_proc_groups));
      }
    }
  }
  if (__kmp_num_proc_groups <= 1) {
    GetSystemInfo(&info);
    __kmp_xproc = info.dwNumberOfProcessors;
  }
#else
  (void)kernel32;
  GetSystemInfo(&info);
  __kmp_xproc = info.dwNumberOfProcessors;
#endif /* KMP_GROUP_AFFINITY */

  // If the OS said there were 0 procs, take a guess and use a value of 2.
  // This is done for Linux* OS, also.  Do we need error / warning?
  if (__kmp_xproc <= 0) {
    __kmp_xproc = 2;
  }

  KA_TRACE(5,
           ("__kmp_runtime_initialize: total processors = %d\n", __kmp_xproc));

  __kmp_str_buf_free(&path);

#if USE_ITT_BUILD
  __kmp_itt_initialize();
#endif /* USE_ITT_BUILD */

  __kmp_init_runtime = TRUE;
} // __kmp_runtime_initialize

void __kmp_runtime_destroy(void) {
  if (!__kmp_init_runtime) {
    return;
  }

#if USE_ITT_BUILD
  __kmp_itt_destroy();
#endif /* USE_ITT_BUILD */

  /* we can't DeleteCriticalsection( & __kmp_win32_section ); */
  /* due to the KX_TRACE() commands */
  KA_TRACE(40, ("__kmp_runtime_destroy\n"));

  if (__kmp_gtid_threadprivate_key) {
    TlsFree(__kmp_gtid_threadprivate_key);
    __kmp_gtid_threadprivate_key = 0;
  }

  __kmp_affinity_uninitialize();
  DeleteCriticalSection(&__kmp_win32_section);

  ntdll = NULL;
  NtQuerySystemInformation = NULL;

#if KMP_ARCH_X86_64
  kernel32 = NULL;
  __kmp_GetActiveProcessorCount = NULL;
  __kmp_GetActiveProcessorGroupCount = NULL;
  __kmp_GetThreadGroupAffinity = NULL;
  __kmp_SetThreadGroupAffinity = NULL;
#endif // KMP_ARCH_X86_64

  __kmp_init_runtime = FALSE;
}

void __kmp_terminate_thread(int gtid) {
  kmp_info_t *th = __kmp_threads[gtid];

  if (!th)
    return;

  KA_TRACE(10, ("__kmp_terminate_thread: kill (%d)\n", gtid));

  if (TerminateThread(th->th.th_info.ds.ds_thread, (DWORD)-1) == FALSE) {
    /* It's OK, the thread may have exited already */
  }
  __kmp_free_handle(th->th.th_info.ds.ds_thread);
}

void __kmp_clear_system_time(void) {
  BOOL status;
  LARGE_INTEGER time;
  status = QueryPerformanceCounter(&time);
  __kmp_win32_time = (kmp_int64)time.QuadPart;
}

void __kmp_initialize_system_tick(void) {
  {
    BOOL status;
    LARGE_INTEGER freq;

    status = QueryPerformanceFrequency(&freq);
    if (!status) {
      DWORD error = GetLastError();
      __kmp_fatal(KMP_MSG(FunctionError, "QueryPerformanceFrequency()"),
                  KMP_ERR(error), __kmp_msg_null);

    } else {
      __kmp_win32_tick = ((double)1.0) / (double)freq.QuadPart;
    }
  }
}

/* Calculate the elapsed wall clock time for the user */

void __kmp_elapsed(double *t) {
  BOOL status;
  LARGE_INTEGER now;
  status = QueryPerformanceCounter(&now);
  *t = ((double)now.QuadPart) * __kmp_win32_tick;
}

/* Calculate the elapsed wall clock tick for the user */

void __kmp_elapsed_tick(double *t) { *t = __kmp_win32_tick; }

void __kmp_read_system_time(double *delta) {
  if (delta != NULL) {
    BOOL status;
    LARGE_INTEGER now;

    status = QueryPerformanceCounter(&now);

    *delta = ((double)(((kmp_int64)now.QuadPart) - __kmp_win32_time)) *
             __kmp_win32_tick;
  }
}

/* Return the current time stamp in nsec */
kmp_uint64 __kmp_now_nsec() {
  LARGE_INTEGER now;
  QueryPerformanceCounter(&now);
  return 1e9 * __kmp_win32_tick * now.QuadPart;
}

extern "C" void *__stdcall __kmp_launch_worker(void *arg) {
  volatile void *stack_data;
  void *exit_val;
  void *padding = 0;
  kmp_info_t *this_thr = (kmp_info_t *)arg;
  int gtid;

  gtid = this_thr->th.th_info.ds.ds_gtid;
  __kmp_gtid_set_specific(gtid);
#ifdef KMP_TDATA_GTID
#error "This define causes problems with LoadLibrary() + declspec(thread) " \
        "on Windows* OS.  See CQ50564, tests kmp_load_library*.c and this MSDN " \
        "reference: http://support.microsoft.com/kb/118816"
//__kmp_gtid = gtid;
#endif

#if USE_ITT_BUILD
  __kmp_itt_thread_name(gtid);
#endif /* USE_ITT_BUILD */

  __kmp_affinity_set_init_mask(gtid, FALSE);

#if KMP_ARCH_X86 || KMP_ARCH_X86_64
  // Set FP control regs to be a copy of the parallel initialization thread's.
  __kmp_clear_x87_fpu_status_word();
  __kmp_load_x87_fpu_control_word(&__kmp_init_x87_fpu_control_word);
  __kmp_load_mxcsr(&__kmp_init_mxcsr);
#endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */

  if (__kmp_stkoffset > 0 && gtid > 0) {
    padding = KMP_ALLOCA(gtid * __kmp_stkoffset);
  }

  KMP_FSYNC_RELEASING(&this_thr->th.th_info.ds.ds_alive);
  this_thr->th.th_info.ds.ds_thread_id = GetCurrentThreadId();
  TCW_4(this_thr->th.th_info.ds.ds_alive, TRUE);

  if (TCR_4(__kmp_gtid_mode) <
      2) { // check stack only if it is used to get gtid
    TCW_PTR(this_thr->th.th_info.ds.ds_stackbase, &stack_data);
    KMP_ASSERT(this_thr->th.th_info.ds.ds_stackgrow == FALSE);
    __kmp_check_stack_overlap(this_thr);
  }
  KMP_MB();
  exit_val = __kmp_launch_thread(this_thr);
  KMP_FSYNC_RELEASING(&this_thr->th.th_info.ds.ds_alive);
  TCW_4(this_thr->th.th_info.ds.ds_alive, FALSE);
  KMP_MB();
  return exit_val;
}

#if KMP_USE_MONITOR
/* The monitor thread controls all of the threads in the complex */

void *__stdcall __kmp_launch_monitor(void *arg) {
  DWORD wait_status;
  kmp_thread_t monitor;
  int status;
  int interval;
  kmp_info_t *this_thr = (kmp_info_t *)arg;

  KMP_DEBUG_ASSERT(__kmp_init_monitor);
  TCW_4(__kmp_init_monitor, 2); // AC: Signal library that monitor has started
  // TODO: hide "2" in enum (like {true,false,started})
  this_thr->th.th_info.ds.ds_thread_id = GetCurrentThreadId();
  TCW_4(this_thr->th.th_info.ds.ds_alive, TRUE);

  KMP_MB(); /* Flush all pending memory write invalidates.  */
  KA_TRACE(10, ("__kmp_launch_monitor: launched\n"));

  monitor = GetCurrentThread();

  /* set thread priority */
  status = SetThreadPriority(monitor, THREAD_PRIORITY_HIGHEST);
  if (!status) {
    DWORD error = GetLastError();
    __kmp_fatal(KMP_MSG(CantSetThreadPriority), KMP_ERR(error), __kmp_msg_null);
  }

  /* register us as monitor */
  __kmp_gtid_set_specific(KMP_GTID_MONITOR);
#ifdef KMP_TDATA_GTID
#error "This define causes problems with LoadLibrary() + declspec(thread) " \
        "on Windows* OS.  See CQ50564, tests kmp_load_library*.c and this MSDN " \
        "reference: http://support.microsoft.com/kb/118816"
//__kmp_gtid = KMP_GTID_MONITOR;
#endif

#if USE_ITT_BUILD
  __kmp_itt_thread_ignore(); // Instruct Intel(R) Threading Tools to ignore
// monitor thread.
#endif /* USE_ITT_BUILD */

  KMP_MB(); /* Flush all pending memory write invalidates.  */

  interval = (1000 / __kmp_monitor_wakeups); /* in milliseconds */

  while (!TCR_4(__kmp_global.g.g_done)) {
    /*  This thread monitors the state of the system */

    KA_TRACE(15, ("__kmp_launch_monitor: update\n"));

    wait_status = WaitForSingleObject(__kmp_monitor_ev, interval);

    if (wait_status == WAIT_TIMEOUT) {
      TCW_4(__kmp_global.g.g_time.dt.t_value,
            TCR_4(__kmp_global.g.g_time.dt.t_value) + 1);
    }

    KMP_MB(); /* Flush all pending memory write invalidates.  */
  }

  KA_TRACE(10, ("__kmp_launch_monitor: finished\n"));

  status = SetThreadPriority(monitor, THREAD_PRIORITY_NORMAL);
  if (!status) {
    DWORD error = GetLastError();
    __kmp_fatal(KMP_MSG(CantSetThreadPriority), KMP_ERR(error), __kmp_msg_null);
  }

  if (__kmp_global.g.g_abort != 0) {
    /* now we need to terminate the worker threads   */
    /* the value of t_abort is the signal we caught */
    int gtid;

    KA_TRACE(10, ("__kmp_launch_monitor: terminate sig=%d\n",
                  (__kmp_global.g.g_abort)));

    /* terminate the OpenMP worker threads */
    /* TODO this is not valid for sibling threads!!
     * the uber master might not be 0 anymore.. */
    for (gtid = 1; gtid < __kmp_threads_capacity; ++gtid)
      __kmp_terminate_thread(gtid);

    __kmp_cleanup();

    Sleep(0);

    KA_TRACE(10,
             ("__kmp_launch_monitor: raise sig=%d\n", __kmp_global.g.g_abort));

    if (__kmp_global.g.g_abort > 0) {
      raise(__kmp_global.g.g_abort);
    }
  }

  TCW_4(this_thr->th.th_info.ds.ds_alive, FALSE);

  KMP_MB();
  return arg;
}
#endif

void __kmp_create_worker(int gtid, kmp_info_t *th, size_t stack_size) {
  kmp_thread_t handle;
  DWORD idThread;

  KA_TRACE(10, ("__kmp_create_worker: try to create thread (%d)\n", gtid));

  th->th.th_info.ds.ds_gtid = gtid;

  if (KMP_UBER_GTID(gtid)) {
    int stack_data;

    /* TODO: GetCurrentThread() returns a pseudo-handle that is unsuitable for
       other threads to use. Is it appropriate to just use GetCurrentThread?
       When should we close this handle?  When unregistering the root? */
    {
      BOOL rc;
      rc = DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
                           GetCurrentProcess(), &th->th.th_info.ds.ds_thread, 0,
                           FALSE, DUPLICATE_SAME_ACCESS);
      KMP_ASSERT(rc);
      KA_TRACE(10, (" __kmp_create_worker: ROOT Handle duplicated, th = %p, "
                    "handle = %" KMP_UINTPTR_SPEC "\n",
                    (LPVOID)th, th->th.th_info.ds.ds_thread));
      th->th.th_info.ds.ds_thread_id = GetCurrentThreadId();
    }
    if (TCR_4(__kmp_gtid_mode) < 2) { // check stack only if used to get gtid
      /* we will dynamically update the stack range if gtid_mode == 1 */
      TCW_PTR(th->th.th_info.ds.ds_stackbase, &stack_data);
      TCW_PTR(th->th.th_info.ds.ds_stacksize, 0);
      TCW_4(th->th.th_info.ds.ds_stackgrow, TRUE);
      __kmp_check_stack_overlap(th);
    }
  } else {
    KMP_MB(); /* Flush all pending memory write invalidates.  */

    /* Set stack size for this thread now. */
    KA_TRACE(10,
             ("__kmp_create_worker: stack_size = %" KMP_SIZE_T_SPEC " bytes\n",
              stack_size));

    stack_size += gtid * __kmp_stkoffset;

    TCW_PTR(th->th.th_info.ds.ds_stacksize, stack_size);
    TCW_4(th->th.th_info.ds.ds_stackgrow, FALSE);

    KA_TRACE(10,
             ("__kmp_create_worker: (before) stack_size = %" KMP_SIZE_T_SPEC
              " bytes, &__kmp_launch_worker = %p, th = %p, &idThread = %p\n",
              (SIZE_T)stack_size, (LPTHREAD_START_ROUTINE)&__kmp_launch_worker,
              (LPVOID)th, &idThread));

    handle = CreateThread(
        NULL, (SIZE_T)stack_size, (LPTHREAD_START_ROUTINE)__kmp_launch_worker,
        (LPVOID)th, STACK_SIZE_PARAM_IS_A_RESERVATION, &idThread);

    KA_TRACE(10,
             ("__kmp_create_worker: (after) stack_size = %" KMP_SIZE_T_SPEC
              " bytes, &__kmp_launch_worker = %p, th = %p, "
              "idThread = %u, handle = %" KMP_UINTPTR_SPEC "\n",
              (SIZE_T)stack_size, (LPTHREAD_START_ROUTINE)&__kmp_launch_worker,
              (LPVOID)th, idThread, handle));

    if (handle == 0) {
      DWORD error = GetLastError();
      __kmp_fatal(KMP_MSG(CantCreateThread), KMP_ERR(error), __kmp_msg_null);
    } else {
      th->th.th_info.ds.ds_thread = handle;
    }

    KMP_MB(); /* Flush all pending memory write invalidates.  */
  }

  KA_TRACE(10, ("__kmp_create_worker: done creating thread (%d)\n", gtid));
}

int __kmp_still_running(kmp_info_t *th) {
  return (WAIT_TIMEOUT == WaitForSingleObject(th->th.th_info.ds.ds_thread, 0));
}

#if KMP_USE_MONITOR
void __kmp_create_monitor(kmp_info_t *th) {
  kmp_thread_t handle;
  DWORD idThread;
  int ideal, new_ideal;

  if (__kmp_dflt_blocktime == KMP_MAX_BLOCKTIME) {
    // We don't need monitor thread in case of MAX_BLOCKTIME
    KA_TRACE(10, ("__kmp_create_monitor: skipping monitor thread because of "
                  "MAX blocktime\n"));
    th->th.th_info.ds.ds_tid = 0; // this makes reap_monitor no-op
    th->th.th_info.ds.ds_gtid = 0;
    TCW_4(__kmp_init_monitor, 2); // Signal to stop waiting for monitor creation
    return;
  }
  KA_TRACE(10, ("__kmp_create_monitor: try to create monitor\n"));

  KMP_MB(); /* Flush all pending memory write invalidates.  */

  __kmp_monitor_ev = CreateEvent(NULL, TRUE, FALSE, NULL);
  if (__kmp_monitor_ev == NULL) {
    DWORD error = GetLastError();
    __kmp_fatal(KMP_MSG(CantCreateEvent), KMP_ERR(error), __kmp_msg_null);
  }
#if USE_ITT_BUILD
  __kmp_itt_system_object_created(__kmp_monitor_ev, "Event");
#endif /* USE_ITT_BUILD */

  th->th.th_info.ds.ds_tid = KMP_GTID_MONITOR;
  th->th.th_info.ds.ds_gtid = KMP_GTID_MONITOR;

  // FIXME - on Windows* OS, if __kmp_monitor_stksize = 0, figure out how
  // to automatically expand stacksize based on CreateThread error code.
  if (__kmp_monitor_stksize == 0) {
    __kmp_monitor_stksize = KMP_DEFAULT_MONITOR_STKSIZE;
  }
  if (__kmp_monitor_stksize < __kmp_sys_min_stksize) {
    __kmp_monitor_stksize = __kmp_sys_min_stksize;
  }

  KA_TRACE(10, ("__kmp_create_monitor: requested stacksize = %d bytes\n",
                (int)__kmp_monitor_stksize));

  TCW_4(__kmp_global.g.g_time.dt.t_value, 0);

  handle =
      CreateThread(NULL, (SIZE_T)__kmp_monitor_stksize,
                   (LPTHREAD_START_ROUTINE)__kmp_launch_monitor, (LPVOID)th,
                   STACK_SIZE_PARAM_IS_A_RESERVATION, &idThread);
  if (handle == 0) {
    DWORD error = GetLastError();
    __kmp_fatal(KMP_MSG(CantCreateThread), KMP_ERR(error), __kmp_msg_null);
  } else
    th->th.th_info.ds.ds_thread = handle;

  KMP_MB(); /* Flush all pending memory write invalidates.  */

  KA_TRACE(10, ("__kmp_create_monitor: monitor created %p\n",
                (void *)th->th.th_info.ds.ds_thread));
}
#endif

/* Check to see if thread is still alive.
   NOTE:  The ExitProcess(code) system call causes all threads to Terminate
   with a exit_val = code.  Because of this we can not rely on exit_val having
   any particular value.  So this routine may return STILL_ALIVE in exit_val
   even after the thread is dead. */

int __kmp_is_thread_alive(kmp_info_t *th, DWORD *exit_val) {
  DWORD rc;
  rc = GetExitCodeThread(th->th.th_info.ds.ds_thread, exit_val);
  if (rc == 0) {
    DWORD error = GetLastError();
    __kmp_fatal(KMP_MSG(FunctionError, "GetExitCodeThread()"), KMP_ERR(error),
                __kmp_msg_null);
  }
  return (*exit_val == STILL_ACTIVE);
}

void __kmp_exit_thread(int exit_status) {
  ExitThread(exit_status);
} // __kmp_exit_thread

// This is a common part for both __kmp_reap_worker() and __kmp_reap_monitor().
static void __kmp_reap_common(kmp_info_t *th) {
  DWORD exit_val;

  KMP_MB(); /* Flush all pending memory write invalidates.  */

  KA_TRACE(
      10, ("__kmp_reap_common: try to reap (%d)\n", th->th.th_info.ds.ds_gtid));

  /* 2006-10-19:
     There are two opposite situations:
     1. Windows* OS keep thread alive after it resets ds_alive flag and
     exits from thread function. (For example, see C70770/Q394281 "unloading of
     dll based on OMP is very slow".)
     2. Windows* OS may kill thread before it resets ds_alive flag.

     Right solution seems to be waiting for *either* thread termination *or*
     ds_alive resetting. */
  {
    // TODO: This code is very similar to KMP_WAIT. Need to generalize
    // KMP_WAIT to cover this usage also.
    void *obj = NULL;
    kmp_uint32 spins;
    kmp_uint64 time;
#if USE_ITT_BUILD
    KMP_FSYNC_SPIN_INIT(obj, (void *)&th->th.th_info.ds.ds_alive);
#endif /* USE_ITT_BUILD */
    KMP_INIT_YIELD(spins);
    KMP_INIT_BACKOFF(time);
    do {
#if USE_ITT_BUILD
      KMP_FSYNC_SPIN_PREPARE(obj);
#endif /* USE_ITT_BUILD */
      __kmp_is_thread_alive(th, &exit_val);
      KMP_YIELD_OVERSUB_ELSE_SPIN(spins, time);
    } while (exit_val == STILL_ACTIVE && TCR_4(th->th.th_info.ds.ds_alive));
#if USE_ITT_BUILD
    if (exit_val == STILL_ACTIVE) {
      KMP_FSYNC_CANCEL(obj);
    } else {
      KMP_FSYNC_SPIN_ACQUIRED(obj);
    }
#endif /* USE_ITT_BUILD */
  }

  __kmp_free_handle(th->th.th_info.ds.ds_thread);

  /* NOTE:  The ExitProcess(code) system call causes all threads to Terminate
     with a exit_val = code.  Because of this we can not rely on exit_val having
     any particular value. */
  if (exit_val == STILL_ACTIVE) {
    KA_TRACE(1, ("__kmp_reap_common: thread still active.\n"));
  } else if ((void *)exit_val != (void *)th) {
    KA_TRACE(1, ("__kmp_reap_common: ExitProcess / TerminateThread used?\n"));
  }

  KA_TRACE(10,
           ("__kmp_reap_common: done reaping (%d), handle = %" KMP_UINTPTR_SPEC
            "\n",
            th->th.th_info.ds.ds_gtid, th->th.th_info.ds.ds_thread));

  th->th.th_info.ds.ds_thread = 0;
  th->th.th_info.ds.ds_tid = KMP_GTID_DNE;
  th->th.th_info.ds.ds_gtid = KMP_GTID_DNE;
  th->th.th_info.ds.ds_thread_id = 0;

  KMP_MB(); /* Flush all pending memory write invalidates.  */
}

#if KMP_USE_MONITOR
void __kmp_reap_monitor(kmp_info_t *th) {
  int status;

  KA_TRACE(10, ("__kmp_reap_monitor: try to reap %p\n",
                (void *)th->th.th_info.ds.ds_thread));

  // If monitor has been created, its tid and gtid should be KMP_GTID_MONITOR.
  // If both tid and gtid are 0, it means the monitor did not ever start.
  // If both tid and gtid are KMP_GTID_DNE, the monitor has been shut down.
  KMP_DEBUG_ASSERT(th->th.th_info.ds.ds_tid == th->th.th_info.ds.ds_gtid);
  if (th->th.th_info.ds.ds_gtid != KMP_GTID_MONITOR) {
    KA_TRACE(10, ("__kmp_reap_monitor: monitor did not start, returning\n"));
    return;
  }

  KMP_MB(); /* Flush all pending memory write invalidates.  */

  status = SetEvent(__kmp_monitor_ev);
  if (status == FALSE) {
    DWORD error = GetLastError();
    __kmp_fatal(KMP_MSG(CantSetEvent), KMP_ERR(error), __kmp_msg_null);
  }
  KA_TRACE(10, ("__kmp_reap_monitor: reaping thread (%d)\n",
                th->th.th_info.ds.ds_gtid));
  __kmp_reap_common(th);

  __kmp_free_handle(__kmp_monitor_ev);

  KMP_MB(); /* Flush all pending memory write invalidates.  */
}
#endif

void __kmp_reap_worker(kmp_info_t *th) {
  KA_TRACE(10, ("__kmp_reap_worker: reaping thread (%d)\n",
                th->th.th_info.ds.ds_gtid));
  __kmp_reap_common(th);
}

#if KMP_HANDLE_SIGNALS

static void __kmp_team_handler(int signo) {
  if (__kmp_global.g.g_abort == 0) {
    // Stage 1 signal handler, let's shut down all of the threads.
    if (__kmp_debug_buf) {
      __kmp_dump_debug_buffer();
    }
    KMP_MB(); // Flush all pending memory write invalidates.
    TCW_4(__kmp_global.g.g_abort, signo);
    KMP_MB(); // Flush all pending memory write invalidates.
    TCW_4(__kmp_global.g.g_done, TRUE);
    KMP_MB(); // Flush all pending memory write invalidates.
  }
} // __kmp_team_handler

static sig_func_t __kmp_signal(int signum, sig_func_t handler) {
  sig_func_t old = signal(signum, handler);
  if (old == SIG_ERR) {
    int error = errno;
    __kmp_fatal(KMP_MSG(FunctionError, "signal"), KMP_ERR(error),
                __kmp_msg_null);
  }
  return old;
}

static void __kmp_install_one_handler(int sig, sig_func_t handler,
                                      int parallel_init) {
  sig_func_t old;
  KMP_MB(); /* Flush all pending memory write invalidates.  */
  KB_TRACE(60, ("__kmp_install_one_handler: called: sig=%d\n", sig));
  if (parallel_init) {
    old = __kmp_signal(sig, handler);
    // SIG_DFL on Windows* OS in NULL or 0.
    if (old == __kmp_sighldrs[sig]) {
      __kmp_siginstalled[sig] = 1;
    } else { // Restore/keep user's handler if one previously installed.
      old = __kmp_signal(sig, old);
    }
  } else {
    // Save initial/system signal handlers to see if user handlers installed.
    // 2009-09-23: It is a dead code. On Windows* OS __kmp_install_signals
    // called once with parallel_init == TRUE.
    old = __kmp_signal(sig, SIG_DFL);
    __kmp_sighldrs[sig] = old;
    __kmp_signal(sig, old);
  }
  KMP_MB(); /* Flush all pending memory write invalidates.  */
} // __kmp_install_one_handler

static void __kmp_remove_one_handler(int sig) {
  if (__kmp_siginstalled[sig]) {
    sig_func_t old;
    KMP_MB(); // Flush all pending memory write invalidates.
    KB_TRACE(60, ("__kmp_remove_one_handler: called: sig=%d\n", sig));
    old = __kmp_signal(sig, __kmp_sighldrs[sig]);
    if (old != __kmp_team_handler) {
      KB_TRACE(10, ("__kmp_remove_one_handler: oops, not our handler, "
                    "restoring: sig=%d\n",
                    sig));
      old = __kmp_signal(sig, old);
    }
    __kmp_sighldrs[sig] = NULL;
    __kmp_siginstalled[sig] = 0;
    KMP_MB(); // Flush all pending memory write invalidates.
  }
} // __kmp_remove_one_handler

void __kmp_install_signals(int parallel_init) {
  KB_TRACE(10, ("__kmp_install_signals: called\n"));
  if (!__kmp_handle_signals) {
    KB_TRACE(10, ("__kmp_install_signals: KMP_HANDLE_SIGNALS is false - "
                  "handlers not installed\n"));
    return;
  }
  __kmp_install_one_handler(SIGINT, __kmp_team_handler, parallel_init);
  __kmp_install_one_handler(SIGILL, __kmp_team_handler, parallel_init);
  __kmp_install_one_handler(SIGABRT, __kmp_team_handler, parallel_init);
  __kmp_install_one_handler(SIGFPE, __kmp_team_handler, parallel_init);
  __kmp_install_one_handler(SIGSEGV, __kmp_team_handler, parallel_init);
  __kmp_install_one_handler(SIGTERM, __kmp_team_handler, parallel_init);
} // __kmp_install_signals

void __kmp_remove_signals(void) {
  int sig;
  KB_TRACE(10, ("__kmp_remove_signals: called\n"));
  for (sig = 1; sig < NSIG; ++sig) {
    __kmp_remove_one_handler(sig);
  }
} // __kmp_remove_signals

#endif // KMP_HANDLE_SIGNALS

/* Put the thread to sleep for a time period */
void __kmp_thread_sleep(int millis) {
  DWORD status;

  status = SleepEx((DWORD)millis, FALSE);
  if (status) {
    DWORD error = GetLastError();
    __kmp_fatal(KMP_MSG(FunctionError, "SleepEx()"), KMP_ERR(error),
                __kmp_msg_null);
  }
}

// Determine whether the given address is mapped into the current address space.
int __kmp_is_address_mapped(void *addr) {
  DWORD status;
  MEMORY_BASIC_INFORMATION lpBuffer;
  SIZE_T dwLength;

  dwLength = sizeof(MEMORY_BASIC_INFORMATION);

  status = VirtualQuery(addr, &lpBuffer, dwLength);

  return !(((lpBuffer.State == MEM_RESERVE) || (lpBuffer.State == MEM_FREE)) ||
           ((lpBuffer.Protect == PAGE_NOACCESS) ||
            (lpBuffer.Protect == PAGE_EXECUTE)));
}

kmp_uint64 __kmp_hardware_timestamp(void) {
  kmp_uint64 r = 0;

  QueryPerformanceCounter((LARGE_INTEGER *)&r);
  return r;
}

/* Free handle and check the error code */
void __kmp_free_handle(kmp_thread_t tHandle) {
  /* called with parameter type HANDLE also, thus suppose kmp_thread_t defined
   * as HANDLE */
  BOOL rc;
  rc = CloseHandle(tHandle);
  if (!rc) {
    DWORD error = GetLastError();
    __kmp_fatal(KMP_MSG(CantCloseHandle), KMP_ERR(error), __kmp_msg_null);
  }
}

int __kmp_get_load_balance(int max) {
  static ULONG glb_buff_size = 100 * 1024;

  // Saved count of the running threads for the thread balance algorithm
  static int glb_running_threads = 0;
  static double glb_call_time = 0; /* Thread balance algorithm call time */

  int running_threads = 0; // Number of running threads in the system.
  NTSTATUS status = 0;
  ULONG buff_size = 0;
  ULONG info_size = 0;
  void *buffer = NULL;
  PSYSTEM_PROCESS_INFORMATION spi = NULL;
  int first_time = 1;

  double call_time = 0.0; // start, finish;

  __kmp_elapsed(&call_time);

  if (glb_call_time &&
      (call_time - glb_call_time < __kmp_load_balance_interval)) {
    running_threads = glb_running_threads;
    goto finish;
  }
  glb_call_time = call_time;

  // Do not spend time on running algorithm if we have a permanent error.
  if (NtQuerySystemInformation == NULL) {
    running_threads = -1;
    goto finish;
  }

  if (max <= 0) {
    max = INT_MAX;
  }

  do {

    if (first_time) {
      buff_size = glb_buff_size;
    } else {
      buff_size = 2 * buff_size;
    }

    buffer = KMP_INTERNAL_REALLOC(buffer, buff_size);
    if (buffer == NULL) {
      running_threads = -1;
      goto finish;
    }
    status = NtQuerySystemInformation(SystemProcessInformation, buffer,
                                      buff_size, &info_size);
    first_time = 0;

  } while (status == STATUS_INFO_LENGTH_MISMATCH);
  glb_buff_size = buff_size;

#define CHECK(cond)                                                            \
  {                                                                            \
    KMP_DEBUG_ASSERT(cond);                                                    \
    if (!(cond)) {                                                             \
      running_threads = -1;                                                    \
      goto finish;                                                             \
    }                                                                          \
  }

  CHECK(buff_size >= info_size);
  spi = PSYSTEM_PROCESS_INFORMATION(buffer);
  for (;;) {
    ptrdiff_t offset = uintptr_t(spi) - uintptr_t(buffer);
    CHECK(0 <= offset &&
          offset + sizeof(SYSTEM_PROCESS_INFORMATION) < info_size);
    HANDLE pid = spi->ProcessId;
    ULONG num = spi->NumberOfThreads;
    CHECK(num >= 1);
    size_t spi_size =
        sizeof(SYSTEM_PROCESS_INFORMATION) + sizeof(SYSTEM_THREAD) * (num - 1);
    CHECK(offset + spi_size <
          info_size); // Make sure process info record fits the buffer.
    if (spi->NextEntryOffset != 0) {
      CHECK(spi_size <=
            spi->NextEntryOffset); // And do not overlap with the next record.
    }
    // pid == 0 corresponds to the System Idle Process. It always has running
    // threads on all cores. So, we don't consider the running threads of this
    // process.
    if (pid != 0) {
      for (int i = 0; i < num; ++i) {
        THREAD_STATE state = spi->Threads[i].State;
        // Count threads that have Ready or Running state.
        // !!! TODO: Why comment does not match the code???
        if (state == StateRunning) {
          ++running_threads;
          // Stop counting running threads if the number is already greater than
          // the number of available cores
          if (running_threads >= max) {
            goto finish;
          }
        }
      }
    }
    if (spi->NextEntryOffset == 0) {
      break;
    }
    spi = PSYSTEM_PROCESS_INFORMATION(uintptr_t(spi) + spi->NextEntryOffset);
  }

#undef CHECK

finish: // Clean up and exit.

  if (buffer != NULL) {
    KMP_INTERNAL_FREE(buffer);
  }

  glb_running_threads = running_threads;

  return running_threads;
} //__kmp_get_load_balance()

// Find symbol from the loaded modules
void *__kmp_lookup_symbol(const char *name) {
  HANDLE process = GetCurrentProcess();
  DWORD needed;
  HMODULE *modules = nullptr;
  if (!EnumProcessModules(process, modules, 0, &needed))
    return nullptr;
  DWORD num_modules = needed / sizeof(HMODULE);
  modules = (HMODULE *)malloc(num_modules * sizeof(HMODULE));
  if (!EnumProcessModules(process, modules, needed, &needed)) {
    free(modules);
    return nullptr;
  }
  void *proc = nullptr;
  for (uint32_t i = 0; i < num_modules; i++) {
    proc = (void *)GetProcAddress(modules[i], name);
    if (proc)
      break;
  }
  free(modules);
  return proc;
}

// Functions for hidden helper task
void __kmp_hidden_helper_worker_thread_wait() {
  KMP_ASSERT(0 && "Hidden helper task is not supported on Windows");
}

void __kmp_do_initialize_hidden_helper_threads() {
  KMP_ASSERT(0 && "Hidden helper task is not supported on Windows");
}

void __kmp_hidden_helper_threads_initz_wait() {
  KMP_ASSERT(0 && "Hidden helper task is not supported on Windows");
}

void __kmp_hidden_helper_initz_release() {
  KMP_ASSERT(0 && "Hidden helper task is not supported on Windows");
}

void __kmp_hidden_helper_main_thread_wait() {
  KMP_ASSERT(0 && "Hidden helper task is not supported on Windows");
}

void __kmp_hidden_helper_main_thread_release() {
  KMP_ASSERT(0 && "Hidden helper task is not supported on Windows");
}

void __kmp_hidden_helper_worker_thread_signal() {
  KMP_ASSERT(0 && "Hidden helper task is not supported on Windows");
}

void __kmp_hidden_helper_threads_deinitz_wait() {
  KMP_ASSERT(0 && "Hidden helper task is not supported on Windows");
}

void __kmp_hidden_helper_threads_deinitz_release() {
  KMP_ASSERT(0 && "Hidden helper task is not supported on Windows");
}
