Browse Source

Drop support for Windows XP

rdb 6 years ago
parent
commit
1bb4a032aa

+ 1 - 1
dtool/src/dtoolbase/dtoolbase.h

@@ -118,7 +118,7 @@
 #ifdef _WIN32_WINNT
 #ifdef _WIN32_WINNT
 #undef _WIN32_WINNT
 #undef _WIN32_WINNT
 #endif
 #endif
-#define _WIN32_WINNT 0x0502
+#define _WIN32_WINNT 0x0600
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus
 #ifndef __STDC_LIMIT_MACROS
 #ifndef __STDC_LIMIT_MACROS

+ 3 - 15
dtool/src/dtoolbase/mutexWin32Impl.I

@@ -11,24 +11,12 @@
  * @date 2006-02-07
  * @date 2006-02-07
  */
  */
 
 
-/**
- *
- */
-INLINE MutexWin32Impl::
-~MutexWin32Impl() {
-  // If the lock has been contended, and we use the Windows XP implementation,
-  // we have a handle to close.  Otherwise, this field will be null.
-  if (_lock[1] != nullptr) {
-    CloseHandle(_lock[1]);
-  }
-}
-
 /**
 /**
  *
  *
  */
  */
 INLINE void MutexWin32Impl::
 INLINE void MutexWin32Impl::
 lock() {
 lock() {
-  _funcs._lock(_lock);
+  AcquireSRWLockExclusive(&_lock);
 }
 }
 
 
 /**
 /**
@@ -36,7 +24,7 @@ lock() {
  */
  */
 INLINE bool MutexWin32Impl::
 INLINE bool MutexWin32Impl::
 try_lock() {
 try_lock() {
-  return (_funcs._try_lock(_lock) != 0);
+  return (TryAcquireSRWLockExclusive(&_lock) != 0);
 }
 }
 
 
 /**
 /**
@@ -44,7 +32,7 @@ try_lock() {
  */
  */
 INLINE void MutexWin32Impl::
 INLINE void MutexWin32Impl::
 unlock() {
 unlock() {
-  _funcs._unlock(_lock);
+  ReleaseSRWLockExclusive(&_lock);
 }
 }
 
 
 /**
 /**

+ 1 - 394
dtool/src/dtoolbase/mutexWin32Impl.cxx

@@ -13,406 +13,13 @@
 
 
 #include "selectThreadImpl.h"
 #include "selectThreadImpl.h"
 
 
-#if defined(WIN32_VC) && !defined(CPPPARSER)
+#ifdef WIN32_VC
 
 
 #include "mutexWin32Impl.h"
 #include "mutexWin32Impl.h"
 
 
 // The number of spins to do before suspending the thread.
 // The number of spins to do before suspending the thread.
 static const unsigned int spin_count = 4000;
 static const unsigned int spin_count = 4000;
 
 
-// Only compile the below nonsense if we're not compiling for a Vista minimum.
-#if _WIN32_WINNT < 0x0600
-
-// If this is true, we will use SRWLock on Windows Vista and above instead of
-// our own implementation.
-static const bool prefer_srwlock = true;
-
-// These configure our own Windows XP implementation.
-static const uintptr_t lock_bit = 0x40000000;
-
-// This gets set to spin_count if we are on a multi-core system.
-static unsigned int effective_spin_count = 0;
-
-/**
- * Windows XP implementation of lock(), which uses a combination of a spinlock
- * and an event.
- */
-static void __stdcall lock_xp(volatile PVOID *lock) {
-  // In the Windows XP case, lock consists of two words: the first one is a
-  // number of waiters plus a bit to indicate that it is locked, the second
-  // one is the handle of an event that is created in case of contention.
-  // The first word can be in the following states:
-  //
-  // lock bit | waiters | meaning
-  // ---------|---------|---------
-  //   unset  |    0    | unlocked
-  //     set  |    0    | locked, nobody waiting on event
-  //     set  |   >0    | locked, at least one thread waiting on event
-  //   unset  |   >0    | handing off lock to one of waiters
-  //
-  // The last state is a little subtle: at this point, the thread that was
-  // holding the lock has stopped holding it, but is about to fire off a
-  // signal to a waiting thread, which will attempt to grab the lock.  In this
-  // case, the waiting thread has first dibs on the lock, and any new threads
-  // will still treat it as locked and wait until there are no more waiters.
-
-  // First try to acquire the lock without suspending the thread.  This only
-  // works if the waiter count is 0; this way, we give priority to threads
-  // that are already waiting for the event.
-  if (InterlockedCompareExchangePointer(lock, (void *)lock_bit, nullptr) == nullptr) {
-    // Got the lock on the first try.
-    return;
-  }
-
-  // On multi-core systems, we keep trying for the configured spin_count.
-  const unsigned int max_spins = effective_spin_count;
-  for (unsigned int spins = 0; spins < max_spins; ++spins) {
-    if (InterlockedCompareExchangePointer(lock, (void *)lock_bit, nullptr) == nullptr) {
-      // We managed to acquire the lock.
-      return;
-    }
-
-    // Emit the pause instruction.  This is NOT a thread yield.
-    YieldProcessor();
-  }
-
-  // Looks like we might have to go to sleep for a while using an event.
-  HANDLE event = lock[1];
-  if (event == nullptr) {
-    // We don't have an event yet.  Create an auto-reset event.
-    HANDLE new_event = CreateEvent(nullptr, false, false, nullptr);
-    while (new_event == nullptr) {
-      // Hmm, out of memory?  Just yield to another thread for now until the
-      // lock is either freed or until we can create an event.
-      Sleep(1);
-      if (InterlockedCompareExchangePointer(lock, (void *)lock_bit, nullptr) == 0) {
-        return;
-      }
-      new_event = CreateEvent(nullptr, false, false, nullptr);
-    }
-
-    // Push the new event.
-    event = InterlockedCompareExchangePointer(lock + 1, new_event, nullptr);
-    if (event == nullptr) {
-      // Set successfully.
-      event = new_event;
-    } else {
-      // Another thread created an event; delete ours and use that one instead.
-      CloseHandle(new_event);
-    }
-  }
-
-  // OK, now we have an event.  We need to let the unlock() function know that
-  // we are waiting.
-  while (true) {
-    uintptr_t waiters = (uintptr_t)lock[0];
-    if (waiters == 0) {
-      // It became unlocked while we were creating an event.  Quick, grab it.
-      if (InterlockedCompareExchangePointer(lock, (void *)lock_bit, nullptr) == nullptr) {
-        return;
-      }
-    }
-
-    // If the lock bit gets unset while we try this, just keep trying.  It
-    // would be dangerous to increment this while the lock bit is unset.
-    waiters |= lock_bit;
-    uintptr_t new_waiters = (uintptr_t)InterlockedCompareExchangePointer(lock, (void *)(waiters + 1), (void *)waiters);
-    if (new_waiters == waiters) {
-      // Made the change successfully.
-      break;
-    } else if (new_waiters == 0) {
-      // It just became unlocked.  Quick, grab it.
-      if (InterlockedCompareExchangePointer(lock, (void *)lock_bit, nullptr) == nullptr) {
-        return;
-      }
-    }
-    YieldProcessor();
-  }
-
-  // Sleep well, thread.
-  while (true) {
-    WaitForSingleObjectEx(event, INFINITE, FALSE);
-
-    // We were woken up.  Does that mean the lock can be ours?
-    while (true) {
-      uintptr_t waiters = (uintptr_t)lock[0];
-      if (waiters & lock_bit) {
-        // False alarm.  Go back to sleep.
-        break;
-      }
-      assert(waiters > 0);
-
-      // Grab the lock immediately, and simultaneously tell it that we are no
-      // longer waiting.
-      uintptr_t new_waiters = (uintptr_t)InterlockedCompareExchangePointer(lock, (void *)((waiters - 1) | lock_bit), (void *)waiters);
-      if (new_waiters == waiters) {
-        // The lock is ours.
-        return;
-      } else if (new_waiters & lock_bit) {
-        // Another thread beat us to it.  Go back to sleep.
-        break;
-      }
-      YieldProcessor();
-    }
-  }
-
-  // Never supposed to get here.
-  assert(false);
-}
-
-/**
- * Windows XP implementation of try_lock().
- */
-static BOOL __stdcall try_lock_xp(volatile PVOID *lock) {
-  return (InterlockedCompareExchangePointer(lock, (void *)lock_bit, nullptr) == nullptr);
-}
-
-/**
- * Windows XP implementation of unlock().
- */
-static void __stdcall unlock_xp(volatile PVOID *lock) {
-  // Clear the lock flag.
-#ifdef _WIN64
-  uintptr_t waiters = _InterlockedAnd64((volatile __int64 *)lock, ~lock_bit);
-#else
-  uintptr_t waiters = _InterlockedAnd((volatile long *)lock, ~lock_bit);
-#endif
-
-  // If this triggers, the lock wasn't held to begin with.
-  assert((waiters & lock_bit) != 0);
-
-  // Have any threads begun to sleep (or are about to) waiting for this lock?
-  if ((waiters & ~lock_bit) == 0) {
-    // No contention, nothing to do.
-    return;
-  } else {
-    // By signalling the auto-resetting event, we wake up one waiting thread.
-    HANDLE event = lock[1];
-    assert(event != nullptr);
-    SetEvent(event);
-  }
-}
-
-/**
- * Windows XP implementation to wait for a condition variable.
- */
-static BOOL __stdcall
-cvar_wait_xp(volatile PVOID *cvar, volatile PVOID *lock, DWORD timeout, ULONG) {
-  // Increment the number of waiters.
-#ifdef _WIN64
-  _InterlockedIncrement64((volatile __int64 *)cvar);
-#else
-  _InterlockedIncrement((volatile long *)cvar);
-#endif
-
-  // Make sure we have two events created: one auto-reset event and one
-  // manual-reset, to handle signal and broadcast, respectively.
-  if (cvar[1] == nullptr) {
-    cvar[1] = CreateEvent(nullptr, false, false, nullptr);
-  }
-  if (cvar[2] == nullptr) {
-    cvar[2] = CreateEvent(nullptr, true, false, nullptr);
-  }
-
-  // It's ok to release the external_mutex here since Win32 manual-reset
-  // events maintain state when used with SetEvent(). This avoids the "lost
-  // wakeup" bug...
-  unlock_xp(lock);
-
-  // Wait for either event to become signaled due to notify() being called or
-  // notify_all() being called.
-  int result = WaitForMultipleObjects(2, (const HANDLE *)(cvar + 1), FALSE, timeout);
-
-  // Decrement the counter.  If it reached zero, we were the last waiter.
-#ifdef _WIN64
-  bool nonzero = (_InterlockedDecrement64((volatile __int64 *)cvar) != 0);
-#else
-  bool nonzero = (_InterlockedDecrement((volatile long *)cvar) != 0);
-#endif
-  bool last_waiter = (result == WAIT_OBJECT_0 + 1 && !nonzero);
-
-  // Some thread called notify_all().
-  if (last_waiter) {
-    // We're the last waiter to be notified or to stop waiting, so reset the
-    // manual event.
-    ResetEvent(cvar[2]);
-  }
-
-  // Reacquire the <external_mutex>.
-  lock_xp(lock);
-  return TRUE;
-}
-
-/**
- * Wakes one thread waiting for a condition variable.
- */
-static void __stdcall
-cvar_notify_one_xp(volatile PVOID *cvar) {
-  // If there are any waiters, signal one of them to wake up by signalling the
-  // auto-reset event.
-  if ((uintptr_t)cvar[0] > 0) {
-    SetEvent(cvar[1]);
-  }
-}
-
-/**
- * Wakes all threads waiting for a condition variable.
- */
-static void __stdcall
-cvar_notify_all_xp(volatile PVOID *cvar) {
-  // If there are any waiters, signal the manual-reset event, which will be
-  // reset by the last thread to wake up.
-  if ((uintptr_t)cvar[0] > 0) {
-    SetEvent(cvar[2]);
-  }
-}
-
-#endif  // _WIN32_WINNT < 0x0600
-
-/**
- * This is put initially in the _lock slot; it makes sure that the lock
- * functions get initialized the first time someone tries to grab a lock.
- */
-void __stdcall MutexWin32Impl::
-lock_initially(volatile PVOID *lock) {
-  MutexWin32Impl::init_lock_funcs();
-  MutexWin32Impl::_funcs._lock(lock);
-}
-
-/**
- * This is put initially in the _try_lock slot; it makes sure that the lock
- * functions get initialized the first time someone tries to grab a lock.
- */
-BOOL __stdcall MutexWin32Impl::
-try_lock_initially(volatile PVOID *lock) {
-  MutexWin32Impl::init_lock_funcs();
-  return MutexWin32Impl::_funcs._try_lock(lock);
-}
-
-/**
- * This gets put initially in the _unlock slot and should never be called,
- * since the initial lock/try_lock implementation will replace the pointers.
- */
-void __stdcall MutexWin32Impl::
-unlock_initially(volatile PVOID *) {
-#if !defined(NDEBUG) || defined(DEBUG_THREADS)
-  std::cerr << "Attempt to release a mutex at static init time before acquiring it!\n";
-  assert(false);
-#endif
-}
-
-/**
- * Same as above for condition variables.
- */
-static BOOL __stdcall
-cvar_wait_initially(volatile PVOID *cvar, volatile PVOID *lock, DWORD timeout, ULONG) {
-#if !defined(NDEBUG) || defined(DEBUG_THREADS)
-  std::cerr << "Attempt to wait for condition variable at static init time before acquiring mutex!\n";
-  assert(false);
-#endif
-  return FALSE;
-}
-
-/**
- * Does nothing.
- */
-static void __stdcall
-noop(volatile PVOID *) {
-}
-
-// We initially set the function pointers to functions that do initialization
-// first.
-MutexWin32Impl::LockFunctions MutexWin32Impl::_funcs = {
-  &MutexWin32Impl::lock_initially,
-  &MutexWin32Impl::try_lock_initially,
-#ifndef NDEBUG
-  &MutexWin32Impl::unlock_initially,
-#else
-  &noop,
-#endif
-
-  &cvar_wait_initially,
-#ifndef NDEBUG
-  &MutexWin32Impl::unlock_initially,
-  &MutexWin32Impl::unlock_initially,
-#else
-  &noop,
-  &noop,
-#endif
-};
-
-/**
- * Called the first time a lock is grabbed.
- */
-void MutexWin32Impl::
-init_lock_funcs() {
-  if (MutexWin32Impl::_funcs._lock != &MutexWin32Impl::lock_initially) {
-    // Already initialized.
-    return;
-  }
-
-#if _WIN32_WINNT >= 0x0600
-  _funcs._lock = (LockFunc)AcquireSRWLockExclusive;
-  _funcs._try_lock = (TryLockFunc)TryAcquireSRWLockExclusive;
-  _funcs._unlock = (LockFunc)ReleaseSRWLockExclusive;
-  _funcs._cvar_wait = (CondWaitFunc)SleepConditionVariableSRW;
-  _funcs._cvar_notify_one = (LockFunc)WakeConditionVariable;
-  _funcs._cvar_notify_all = (LockFunc)WakeAllConditionVariable;
-#else
-  // We don't need to be very thread safe here.  This can only ever be called
-  // at static init time, when there is still only one thread.
-  if (prefer_srwlock) {
-    HMODULE module = GetModuleHandleA("kernel32");
-    if (module != nullptr) {
-      _funcs._lock = (LockFunc)GetProcAddress(module, "AcquireSRWLockExclusive");
-      _funcs._try_lock = (TryLockFunc)GetProcAddress(module, "TryAcquireSRWLockExclusive");
-      _funcs._unlock = (LockFunc)GetProcAddress(module, "ReleaseSRWLockExclusive");
-      _funcs._cvar_wait = (CondWaitFunc)GetProcAddress(module, "SleepConditionVariableSRW");
-      _funcs._cvar_notify_one = (LockFunc)GetProcAddress(module, "WakeConditionVariable");
-      _funcs._cvar_notify_all = (LockFunc)GetProcAddress(module, "WakeAllConditionVariable");
-      if (_funcs._lock != nullptr &&
-          _funcs._try_lock != nullptr &&
-          _funcs._unlock != nullptr &&
-          _funcs._cvar_wait != nullptr &&
-          _funcs._cvar_notify_one != nullptr &&
-          _funcs._cvar_notify_all != nullptr) {
-        return;
-      }
-    }
-  }
-
-  // Fall back to our custom Event-based implementation on Windows XP.
-  _funcs._lock = &lock_xp;
-  _funcs._try_lock = &try_lock_xp;
-  _funcs._unlock = &unlock_xp;
-  _funcs._cvar_wait = &cvar_wait_xp;
-  _funcs._cvar_notify_one = &cvar_notify_one_xp;
-  _funcs._cvar_notify_all = &cvar_notify_all_xp;
-
-  // Are we on a multi-core system?  If so, enable the spinlock.
-  SYSTEM_INFO sysinfo;
-  GetSystemInfo(&sysinfo);
-  if (sysinfo.dwNumberOfProcessors > 1) {
-    effective_spin_count = spin_count;
-  } else {
-    effective_spin_count = 0;
-  }
-#endif  // _WIN32_WINNT < 0x0600
-}
-
-/**
- * Ensures that the lock functions are initialized at static init time.  This
- * prevents us from having to implement synchronization in our initialization.
- */
-class LockFuncsInitializer {
-public:
-  LockFuncsInitializer() {
-    MutexWin32Impl::init_lock_funcs();
-  }
-};
-
-static LockFuncsInitializer _lock_funcs_init;
-
 /**
 /**
  *
  *
  */
  */

+ 2 - 32
dtool/src/dtoolbase/mutexWin32Impl.h

@@ -31,7 +31,7 @@ class EXPCL_DTOOL_DTOOLBASE MutexWin32Impl {
 public:
 public:
   constexpr MutexWin32Impl() = default;
   constexpr MutexWin32Impl() = default;
   MutexWin32Impl(const MutexWin32Impl &copy) = delete;
   MutexWin32Impl(const MutexWin32Impl &copy) = delete;
-  INLINE ~MutexWin32Impl();
+  ~MutexWin32Impl() = default;
 
 
   MutexWin32Impl &operator = (const MutexWin32Impl &copy) = delete;
   MutexWin32Impl &operator = (const MutexWin32Impl &copy) = delete;
 
 
@@ -40,38 +40,8 @@ public:
   INLINE bool try_lock();
   INLINE bool try_lock();
   INLINE void unlock();
   INLINE void unlock();
 
 
-  static void init_lock_funcs();
-
-private:
-#ifndef CPPPARSER
-  // Store function pointers; these point directly to the SRWLock Win32 API
-  // functions on Vista and above, or to our own implementation on Windows XP.
-  typedef void (__stdcall *LockFunc)(volatile PVOID *lock);
-  typedef BOOL (__stdcall *TryLockFunc)(volatile PVOID *lock);
-  typedef BOOL (__stdcall *CondWaitFunc)(volatile PVOID *cvar, volatile PVOID *lock, DWORD, ULONG);
-
-  struct LockFunctions {
-    LockFunc _lock;
-    TryLockFunc _try_lock;
-    LockFunc _unlock;
-
-    CondWaitFunc _cvar_wait;
-    LockFunc _cvar_notify_one;
-    LockFunc _cvar_notify_all;
-  };
-
-  static LockFunctions _funcs;
-
-  static void __stdcall lock_initially(volatile PVOID *lock);
-  static BOOL __stdcall try_lock_initially(volatile PVOID *lock);
-  static void __stdcall unlock_initially(volatile PVOID *lock);
-#endif
-
 private:
 private:
-  // In the SRWLock implementation, only the first field is used.  On Windows
-  // XP, the first field contains a waiter count and lock bit, and the second
-  // field contains an Event handle if contention has occurred.
-  volatile PVOID _lock[2] = {nullptr, nullptr};
+  SRWLOCK _lock = SRWLOCK_INIT;
 
 
   friend class ConditionVarWin32Impl;
   friend class ConditionVarWin32Impl;
 };
 };

+ 2 - 0
dtool/src/parser-inc/synchapi.h

@@ -4,7 +4,9 @@
 #include "winnt.h"
 #include "winnt.h"
 
 
 #define SRWLOCK_INIT RTL_SRWLOCK_INIT
 #define SRWLOCK_INIT RTL_SRWLOCK_INIT
+#define CONDITION_VARIABLE_INIT RTL_CONDITION_VARIABLE_INIT
 
 
 typedef RTL_SRWLOCK SRWLOCK, *PSRWLOCK;
 typedef RTL_SRWLOCK SRWLOCK, *PSRWLOCK;
+typedef RTL_CONDITION_VARIABLE CONDITION_VARIABLE, *PCONDITION_VARIABLE;
 
 
 #endif
 #endif

+ 1 - 0
dtool/src/parser-inc/windows.h

@@ -20,6 +20,7 @@
 #define WINDOWS_H
 #define WINDOWS_H
 
 
 #include <wtypes.h>
 #include <wtypes.h>
+#include <synchapi.h>
 
 
 #ifdef _WIN64
 #ifdef _WIN64
 typedef int HALF_PTR;
 typedef int HALF_PTR;

+ 2 - 0
dtool/src/parser-inc/winnt.h

@@ -13,4 +13,6 @@ typedef struct _RTL_CONDITION_VARIABLE {
   PVOID Ptr;
   PVOID Ptr;
 } RTL_CONDITION_VARIABLE, *PRTL_CONDITION_VARIABLE;
 } RTL_CONDITION_VARIABLE, *PRTL_CONDITION_VARIABLE;
 
 
+#define RTL_CONDITION_VARIABLE_INIT {0}
+
 #endif
 #endif

+ 5 - 8
makepanda/makepanda.py

@@ -1034,11 +1034,8 @@ def CompileCxx(obj,src,opts):
                 cmd += "/favor:blend "
                 cmd += "/favor:blend "
             cmd += "/wd4996 /wd4275 /wd4273 "
             cmd += "/wd4996 /wd4275 /wd4273 "
 
 
-            # We still target Windows XP.
-            cmd += "/DWINVER=0x501 "
-            # Work around a WinXP/2003 bug when using VS 2015+.
-            if SDK.get("VISUALSTUDIO_VERSION") >= (14,0):
-                cmd += "/Zc:threadSafeInit- "
+            # Set the minimum version to Windows Vista.
+            cmd += "/DWINVER=0x600 "
 
 
             cmd += "/Fo" + obj + " /nologo /c"
             cmd += "/Fo" + obj + " /nologo /c"
             if GetTargetArch() != 'x64' and (not PkgSkip("SSE2") or 'SSE2' in opts):
             if GetTargetArch() != 'x64' and (not PkgSkip("SSE2") or 'SSE2' in opts):
@@ -1089,7 +1086,7 @@ def CompileCxx(obj,src,opts):
             if GetTargetArch() == 'x64':
             if GetTargetArch() == 'x64':
                 cmd += "/favor:blend "
                 cmd += "/favor:blend "
             cmd += "/wd4996 /wd4275 /wd4267 /wd4101 /wd4273 "
             cmd += "/wd4996 /wd4275 /wd4267 /wd4101 /wd4273 "
-            cmd += "/DWINVER=0x501 "
+            cmd += "/DWINVER=0x600 "
             cmd += "/Fo" + obj + " /c"
             cmd += "/Fo" + obj + " /c"
             for x in ipath: cmd += " /I" + x
             for x in ipath: cmd += " /I" + x
             for (opt,dir) in INCDIRECTORIES:
             for (opt,dir) in INCDIRECTORIES:
@@ -1575,9 +1572,9 @@ def CompileLink(dll, obj, opts):
             subsystem = GetValueOption(opts, "SUBSYSTEM:") or "CONSOLE"
             subsystem = GetValueOption(opts, "SUBSYSTEM:") or "CONSOLE"
             cmd += " /SUBSYSTEM:" + subsystem
             cmd += " /SUBSYSTEM:" + subsystem
             if GetTargetArch() == 'x64':
             if GetTargetArch() == 'x64':
-                cmd += ",5.02"
+                cmd += ",6.00"
             else:
             else:
-                cmd += ",5.01"
+                cmd += ",6.00"
 
 
             if dll.endswith(".dll") or dll.endswith(".pyd"):
             if dll.endswith(".dll") or dll.endswith(".pyd"):
                 cmd += ' /IMPLIB:' + GetOutputDir() + '/lib/' + os.path.splitext(os.path.basename(dll))[0] + ".lib"
                 cmd += ' /IMPLIB:' + GetOutputDir() + '/lib/' + os.path.splitext(os.path.basename(dll))[0] + ".lib"

+ 1 - 1
panda/src/device/winInputDeviceManager.cxx

@@ -54,7 +54,7 @@ WinInputDeviceManager() :
   _xinput_device2.local_object();
   _xinput_device2.local_object();
   _xinput_device3.local_object();
   _xinput_device3.local_object();
 
 
-  // This function is only available in Vista and later, so we use a wrapper.
+  // This function is not available in the 7.1A SDK, so we use a wrapper.
   HMODULE module = LoadLibraryA("cfgmgr32.dll");
   HMODULE module = LoadLibraryA("cfgmgr32.dll");
   if (module) {
   if (module) {
     _CM_Get_DevNode_PropertyW = (pCM_Get_DevNode_Property)GetProcAddress(module, "CM_Get_DevNode_PropertyW");
     _CM_Get_DevNode_PropertyW = (pCM_Get_DevNode_Property)GetProcAddress(module, "CM_Get_DevNode_PropertyW");

+ 7 - 19
panda/src/express/trueClock.cxx

@@ -113,27 +113,15 @@ get_short_raw_time() {
 /**
 /**
  *
  *
  */
  */
-typedef BOOL (WINAPI * PFNSETPROCESSAFFINITYMASK)(HANDLE, DWORD_PTR);
-typedef BOOL (WINAPI * PFNGETPROCESSAFFINITYMASK)(HANDLE, DWORD_PTR*, DWORD_PTR*);
-
 bool TrueClock::
 bool TrueClock::
 set_cpu_affinity(uint32_t mask) const {
 set_cpu_affinity(uint32_t mask) const {
-  HMODULE hker = GetModuleHandle("kernel32");
-  if (hker != 0) {
-    PFNGETPROCESSAFFINITYMASK gp = (PFNGETPROCESSAFFINITYMASK)
-      GetProcAddress(hker, "GetProcessAffinityMask");
-    PFNSETPROCESSAFFINITYMASK sp = (PFNSETPROCESSAFFINITYMASK)
-      GetProcAddress(hker, "SetProcessAffinityMask");
-    if (gp != 0 && sp != 0) {
-      DWORD proc_mask;
-      DWORD sys_mask;
-      if (gp(GetCurrentProcess(), (PDWORD_PTR)&proc_mask, (PDWORD_PTR)&sys_mask)) {
-        // make sure we don't reference CPUs that don't exist
-        proc_mask = mask & sys_mask;
-        if (proc_mask) {
-          return sp(GetCurrentProcess(), proc_mask) != 0;
-        }
-      }
+  DWORD proc_mask;
+  DWORD sys_mask;
+  if (GetProcessAffinityMask(GetCurrentProcess(), (PDWORD_PTR)&proc_mask, (PDWORD_PTR)&sys_mask)) {
+    // make sure we don't reference CPUs that don't exist
+    proc_mask = mask & sys_mask;
+    if (proc_mask) {
+      return SetProcessAffinityMask(GetCurrentProcess(), proc_mask) != 0;
     }
     }
   }
   }
   return false;
   return false;

+ 4 - 19
panda/src/pipeline/conditionVarWin32Impl.I

@@ -18,27 +18,12 @@ INLINE ConditionVarWin32Impl::
 ConditionVarWin32Impl(MutexWin32Impl &mutex) : _mutex(mutex) {
 ConditionVarWin32Impl(MutexWin32Impl &mutex) : _mutex(mutex) {
 }
 }
 
 
-/**
- *
- */
-INLINE ConditionVarWin32Impl::
-~ConditionVarWin32Impl() {
-  // These fields are only set in the Windows XP implementation, when these
-  // both contain events.
-  if (_cvar[1] != nullptr) {
-    CloseHandle(_cvar[1]);
-  }
-  if (_cvar[2] != nullptr) {
-    CloseHandle(_cvar[2]);
-  }
-}
-
 /**
 /**
  *
  *
  */
  */
 INLINE void ConditionVarWin32Impl::
 INLINE void ConditionVarWin32Impl::
 wait() {
 wait() {
-  MutexWin32Impl::_funcs._cvar_wait(_cvar, _mutex._lock, INFINITE, 0);
+  SleepConditionVariableSRW(&_cvar, &_mutex._lock, INFINITE, 0);
 }
 }
 
 
 /**
 /**
@@ -46,7 +31,7 @@ wait() {
  */
  */
 INLINE void ConditionVarWin32Impl::
 INLINE void ConditionVarWin32Impl::
 wait(double timeout) {
 wait(double timeout) {
-  MutexWin32Impl::_funcs._cvar_wait(_cvar, _mutex._lock, (DWORD)(timeout * 1000.0), 0);
+  SleepConditionVariableSRW(&_cvar, &_mutex._lock, (DWORD)(timeout * 1000.0), 0);
 }
 }
 
 
 /**
 /**
@@ -54,7 +39,7 @@ wait(double timeout) {
  */
  */
 INLINE void ConditionVarWin32Impl::
 INLINE void ConditionVarWin32Impl::
 notify() {
 notify() {
-  MutexWin32Impl::_funcs._cvar_notify_one(_cvar);
+  WakeConditionVariable(&_cvar);
 }
 }
 
 
 /**
 /**
@@ -62,5 +47,5 @@ notify() {
  */
  */
 INLINE void ConditionVarWin32Impl::
 INLINE void ConditionVarWin32Impl::
 notify_all() {
 notify_all() {
-  MutexWin32Impl::_funcs._cvar_notify_all(_cvar);
+  WakeAllConditionVariable(&_cvar);
 }
 }

+ 2 - 18
panda/src/pipeline/conditionVarWin32Impl.h

@@ -26,23 +26,11 @@ class MutexWin32Impl;
 
 
 /**
 /**
  * Uses Windows native calls to implement a ConditionVar.
  * Uses Windows native calls to implement a ConditionVar.
- *
- * On Windows Vista and above, we use the system's native condition variables.
- *
- * On Windows XP, we follow the "SetEvent" implementation suggested by
- * http://www.cs.wustl.edu/~schmidt/win32-cv-1.html . This allows us to
- * implement both notify() and notify_all().
- *
- * As described by the above reference, this implementation suffers from a few
- * weaknesses; in particular, it does not necessarily wake up all threads
- * fairly; and it may sometimes incorrectly wake up a thread that was not
- * waiting at the time notify() was called.  But we figure it's good enough
- * for our purposes.
  */
  */
 class EXPCL_PANDA_PIPELINE ConditionVarWin32Impl {
 class EXPCL_PANDA_PIPELINE ConditionVarWin32Impl {
 public:
 public:
   INLINE ConditionVarWin32Impl(MutexWin32Impl &mutex);
   INLINE ConditionVarWin32Impl(MutexWin32Impl &mutex);
-  INLINE ~ConditionVarWin32Impl();
+  ~ConditionVarWin32Impl() = default;
 
 
   INLINE void wait();
   INLINE void wait();
   INLINE void wait(double timeout);
   INLINE void wait(double timeout);
@@ -51,11 +39,7 @@ public:
 
 
 private:
 private:
   MutexWin32Impl &_mutex;
   MutexWin32Impl &_mutex;
-
-  // On Windows XP, the first field contains a Signal (auto-reset) event,
-  // the second field a broadcast (manual reset) event, third a waiter count.
-  // On Windows Vista and above, the first contains a PCONDITION_VARIABLE.
-  volatile PVOID _cvar[3] = {nullptr, nullptr, nullptr};
+  CONDITION_VARIABLE _cvar = CONDITION_VARIABLE_INIT;
 };
 };
 
 
 #include "conditionVarWin32Impl.I"
 #include "conditionVarWin32Impl.I"

+ 9 - 26
panda/src/windisplay/winDetectDx.h

@@ -32,8 +32,6 @@ static DISPLAY_FORMAT display_format_array [ ] = {
   D3DFMT_UNKNOWN,      0, FALSE,
   D3DFMT_UNKNOWN,      0, FALSE,
 };
 };
 
 
-typedef BOOL (WINAPI *GlobalMemoryStatusExType) (LPMEMORYSTATUSEX lpBuffer);
-
 static int d3d_format_to_bits_per_pixel (D3DFORMAT d3d_format) {
 static int d3d_format_to_bits_per_pixel (D3DFORMAT d3d_format) {
   int format_index;
   int format_index;
   int bits_per_pixel;
   int bits_per_pixel;
@@ -612,32 +610,17 @@ static int get_display_information (DisplaySearchParameters &display_search_para
   }
   }
 
 
   // memory
   // memory
-  bool memory_state;
-  HMODULE kernel32_dll;
-
-  memory_state = false;
-  kernel32_dll = LoadLibrary ("kernel32.dll");
-  if (kernel32_dll) {
-    GlobalMemoryStatusExType GlobalMemoryStatusExFunction;
-
-    GlobalMemoryStatusExFunction = (GlobalMemoryStatusExType) GetProcAddress (kernel32_dll, "GlobalMemoryStatusEx");
-    if (GlobalMemoryStatusExFunction) {
-      MEMORYSTATUSEX memory_status;
-
-      memory_status.dwLength = sizeof (MEMORYSTATUSEX);
-      if (GlobalMemoryStatusExFunction (&memory_status)) {
-        physical_memory = memory_status.ullTotalPhys;
-        available_physical_memory = memory_status.ullAvailPhys;
-        memory_state = true;
-      }
-    }
-    FreeLibrary (kernel32_dll);
-  }
-  if (memory_state == false) {
+  MEMORYSTATUSEX memory_status;
+  memory_status.dwLength = sizeof(MEMORYSTATUSEX);
+
+  if (GlobalMemoryStatusEx(&memory_status)) {
+    physical_memory = memory_status.ullTotalPhys;
+    available_physical_memory = memory_status.ullAvailPhys;
+  } else  {
     MEMORYSTATUS memory_status;
     MEMORYSTATUS memory_status;
+    memory_status.dwLength = sizeof(MEMORYSTATUS);
 
 
-    memory_status.dwLength = sizeof (MEMORYSTATUS);
-    GlobalMemoryStatus (&memory_status);
+    GlobalMemoryStatus(&memory_status);
 
 
     physical_memory = memory_status.dwTotalPhys;
     physical_memory = memory_status.dwTotalPhys;
     available_physical_memory = memory_status.dwAvailPhys;
     available_physical_memory = memory_status.dwAvailPhys;

+ 2 - 14
panda/src/windisplay/winGraphicsPipe.cxx

@@ -155,23 +155,11 @@ count_number_of_cpus(DisplayInformation *display_information) {
   int num_cpu_cores = 0;
   int num_cpu_cores = 0;
   int num_logical_cpus = 0;
   int num_logical_cpus = 0;
 
 
-  // Get a pointer to the GetLogicalProcessorInformation function.
-  typedef BOOL (WINAPI *LPFN_GLPI)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION,
-                                   PDWORD);
-  LPFN_GLPI glpi;
-  glpi = (LPFN_GLPI)GetProcAddress(GetModuleHandle(TEXT("kernel32")),
-                                    "GetLogicalProcessorInformation");
-  if (glpi == nullptr) {
-    windisplay_cat.info()
-      << "GetLogicalProcessorInformation is not supported.\n";
-    return;
-  }
-
   // Allocate a buffer to hold the result of the
   // Allocate a buffer to hold the result of the
   // GetLogicalProcessorInformation call.
   // GetLogicalProcessorInformation call.
   PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = nullptr;
   PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = nullptr;
   DWORD buffer_length = 0;
   DWORD buffer_length = 0;
-  DWORD rc = glpi(buffer, &buffer_length);
+  DWORD rc = GetLogicalProcessorInformation(buffer, &buffer_length);
   while (!rc) {
   while (!rc) {
     if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
     if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
       if (buffer != nullptr) {
       if (buffer != nullptr) {
@@ -186,7 +174,7 @@ count_number_of_cpus(DisplayInformation *display_information) {
         << "\n";
         << "\n";
       return;
       return;
     }
     }
-    rc = glpi(buffer, &buffer_length);
+    rc = GetLogicalProcessorInformation(buffer, &buffer_length);
   }
   }
 
 
   // Now get the results.
   // Now get the results.