]> git.saurik.com Git - wxWidgets.git/commitdiff
implemented GetCPUCount() and SetConcurrency() for Win32
authorVadim Zeitlin <vadim@wxwidgets.org>
Mon, 6 Dec 1999 14:06:21 +0000 (14:06 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Mon, 6 Dec 1999 14:06:21 +0000 (14:06 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4840 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

src/msw/thread.cpp

index 35838d9a2985eaec4ceee4640744c12db39975d2..df5e9a437f2ae0de74d3185acb2b10db8e0c730a 100644 (file)
@@ -529,13 +529,106 @@ void wxThread::Sleep(unsigned long milliseconds)
 
 int wxThread::GetCPUCount()
 {
-    return -1;
+    SYSTEM_INFO si;
+    GetSystemInfo(&si);
+
+    return si.dwNumberOfProcessors;
 }
 
 bool wxThread::SetConcurrency(size_t level)
 {
+    wxASSERT_MSG( IsMain(), _T("should only be called from the main thread") );
+
     // ok only for the default one
-    return level == 0;
+    if ( level == 0 )
+        return 0;
+
+    // get system affinity mask first
+    HANDLE hProcess = ::GetCurrentProcess();
+    DWORD dwProcMask, dwSysMask;
+    if ( ::GetProcessAffinityMask(hProcess, &dwProcMask, &dwSysMask) == 0 )
+    {
+        wxLogLastError(_T("GetProcessAffinityMask"));
+
+        return FALSE;
+    }
+
+    // how many CPUs have we got?
+    if ( dwSysMask == 1 )
+    {
+        // don't bother with all this complicated stuff - on a single
+        // processor system it doesn't make much sense anyhow
+        return level == 1;
+    }
+
+    // calculate the process mask: it's a bit vector with one bit per
+    // processor; we want to schedule the process to run on first level
+    // CPUs
+    DWORD bit = 1;
+    while ( bit )
+    {
+        if ( dwSysMask & bit )
+        {
+            // ok, we can set this bit
+            dwProcMask |= bit;
+
+            // another process added
+            if ( !--level )
+            {
+                // and that's enough
+                break;
+            }
+        }
+
+        // next bit
+        bit <<= 1;
+    }
+
+    // could we set all bits?
+    if ( level != 0 )
+    {
+        wxLogDebug(_T("bad level %u in wxThread::SetConcurrency()"), level);
+
+        return FALSE;
+    }
+
+    // set it: we can't link to SetProcessAffinityMask() because it doesn't
+    // exist in Win9x, use RT binding instead
+
+    typedef BOOL (*SETPROCESSAFFINITYMASK)(HANDLE, DWORD *);
+
+    // can use static var because we're always in the main thread here
+    static SETPROCESSAFFINITYMASK pfnSetProcessAffinityMask = NULL;
+
+    if ( !pfnSetProcessAffinityMask )
+    {
+        HMODULE hModKernel = ::LoadLibrary(_T("kernel32"));
+        if ( hModKernel )
+        {
+            pfnSetProcessAffinityMask = (SETPROCESSAFFINITYMASK)
+                ::GetProcAddress(hModKernel, _T("SetProcessAffinityMask"));
+        }
+
+        // we've discovered a MT version of Win9x!
+        wxASSERT_MSG( pfnSetProcessAffinityMask,
+                      _T("this system has several CPUs but no "
+                         "SetProcessAffinityMask function?") );
+    }
+
+    if ( !pfnSetProcessAffinityMask )
+    {
+        // msg given above - do it only once
+        return FALSE;
+    }
+
+    if ( pfnSetProcessAffinityMask(hProcess, &dwProcMask) == 0 )
+    {
+        wxLogLastError(_T("SetProcessAffinityMask"));
+
+        return FALSE;
+    }
+
+    return TRUE;
 }
 
 // ctor and dtor