+ wxLogSysError(_("Can not resume thread %x"), m_hThread);
+
+ return false;
+ }
+
+ // don't change the state from STATE_EXITED because it's special and means
+ // we are going to terminate without running any user code - if we did it,
+ // the code in WaitForTerminate() wouldn't work
+ if ( m_state != STATE_EXITED )
+ {
+ m_state = STATE_RUNNING;
+ }
+
+ return true;
+}
+
+// static functions
+// ----------------
+
+wxThread *wxThread::This()
+{
+ wxThread *thread = (wxThread *)::TlsGetValue(gs_tlsThisThread);
+
+ // be careful, 0 may be a valid return value as well
+ if ( !thread && (::GetLastError() != NO_ERROR) )
+ {
+ wxLogSysError(_("Couldn't get the current thread pointer"));
+
+ // return NULL...
+ }
+
+ return thread;
+}
+
+bool wxThread::IsMain()
+{
+ return ::GetCurrentThreadId() == gs_idMainThread || gs_idMainThread == 0;
+}
+
+void wxThread::Yield()
+{
+ // 0 argument to Sleep() is special and means to just give away the rest of
+ // our timeslice
+ ::Sleep(0);
+}
+
+void wxThread::Sleep(unsigned long milliseconds)
+{
+ ::Sleep(milliseconds);
+}
+
+int wxThread::GetCPUCount()
+{
+ SYSTEM_INFO si;
+ GetSystemInfo(&si);
+
+ return si.dwNumberOfProcessors;
+}
+
+unsigned long wxThread::GetCurrentId()
+{
+ return (unsigned long)::GetCurrentThreadId();
+}
+
+bool wxThread::SetConcurrency(size_t level)
+{
+#ifdef __WXWINCE__
+ wxUnusedVar(level);
+ return false;
+#else
+ wxASSERT_MSG( IsMain(), _T("should only be called from the main thread") );
+
+ // ok only for the default one
+ if ( level == 0 )
+ return 0;
+
+ // get system affinity mask first
+ HANDLE hProcess = ::GetCurrentProcess();
+ DWORD_PTR 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, "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"));