Main changes from HEAD:
1) Implements GetNumaHighestNodeNumber which simulates a typical single node 
system.
2) Implements GetNumaNodeProcessorMask which returns the global processor 
affinity mask for node 0, otherwise returns an error.
3) Implements GetNumaAvailableMemoryNode which returns available physical 
memory for node 0, otherwise returns an error.

This much of the behavior was observed based on a single processor (4 cores) 
Windows 7 system. These functions are utilized by the synchronization and 
threading primitives incorporated in the MSVC 2012 and newer C and C++ runtime 
libraries. concrt.h/Concurrency::critical_section, which is used by both 
std::mutex and std::thread, will throw an exception the moment the object is 
locked if GetNumaHighestNodeNumber fails, and there are at least a few examples 
of software which don't bother to catch this exception and thus crash, such as 
the alpha version of Cube World, and certain versions of the foo_wave_seekbar 
component for the foobar2000 audio player. The associated scheduling code 
appears to make use of GetNumaNodeProcessorMask as well to control how many 
threads are allowed to spin up at once, or so I guess without looking very 
deeply into the CRT source code.

From a7ae257aed539fc72f0bc37c85030f8abc181389 Mon Sep 17 00:00:00 2001
From: Chris Moeller <kod...@gmail.com>
Date: Sun, 28 Jul 2013 16:23:05 -0700
Subject: kernel32: Implemented basic NUMA functions to replace the stubs

---
 dlls/kernel32/process.c |   42 +++++++++++++++++++++++++++++++++---------
 1 file changed, 33 insertions(+), 9 deletions(-)

diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index 6ce43d8..2513be6 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -3849,9 +3849,10 @@ HRESULT WINAPI 
RegisterApplicationRecoveryCallback(APPLICATION_RECOVERY_CALLBACK
  */
 BOOL WINAPI GetNumaHighestNodeNumber(PULONG highestnode)
 {
-    FIXME("(%p): stub\n", highestnode);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    TRACE("(%p)\n", highestnode);
+    *highestnode = 0;
+    SetLastError(0);
+    return TRUE;
 }
 
 /**********************************************************************
@@ -3859,9 +3860,20 @@ BOOL WINAPI GetNumaHighestNodeNumber(PULONG highestnode)
  */
 BOOL WINAPI GetNumaNodeProcessorMask(UCHAR node, PULONGLONG mask)
 {
-    FIXME("(%c %p): stub\n", node, mask);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    TRACE("(%c %p)\n", node, mask);
+    if (node == 0)
+    {
+        DWORD system_mask;
+        GetProcessAffinityMask(GetCurrentProcess(), NULL, &system_mask);
+        *mask = system_mask;
+        SetLastError(0);
+        return TRUE;
+    }
+    else
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
 }
 
 /**********************************************************************
@@ -3869,9 +3881,21 @@ BOOL WINAPI GetNumaNodeProcessorMask(UCHAR node, 
PULONGLONG mask)
  */
 BOOL WINAPI GetNumaAvailableMemoryNode(UCHAR node, PULONGLONG available_bytes)
 {
-    FIXME("(%c %p): stub\n", node, available_bytes);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    TRACE("(%c %p)\n", node, available_bytes);
+    if (node == 0)
+    {
+        MEMORYSTATUSEX msx;
+        msx.dwLength = sizeof(msx);
+        GlobalMemoryStatusEx(&msx);
+        *available_bytes = msx.ullAvailPhys;
+        SetLastError(0);
+        return TRUE;
+    }
+    else
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
 }
 
 /**********************************************************************
-- 
1.7.10.2 (Apple Git-33)



Reply via email to