//------------------------------------------------------------------------ bool ThreadManagerSerial::startThread(int id) { assert(isPrimaryThread()); // make it go, if possible bool output = ThreadManager::startThread(id); if(!output) { // deal with extra states introduced to parallel execution // NOTE: this will invalidate a pending serialization request int status = SetThreadStatus( id, THREAD_STATUS_PARALLEL_TO_SERIAL_STOPPED_REQUEST, THREAD_STATUS_RUNNING_REQUEST ); output = output || (status == THREAD_STATUS_RUNNING_REQUEST); // also deal with serial states // NOTE: this will invalidate a pending parallelization request status = SetThreadStatus( id, ( THREAD_STATUS_SERIAL_STOPPED | THREAD_STATUS_SERIAL_TO_PARALLEL_STOPPED_REQUEST ), THREAD_STATUS_SERIAL_RUNNING ); output = output || (status == THREAD_STATUS_SERIAL_RUNNING); } return output; }
//------------------------------------------------------------------------ bool ThreadManagerSerial::setThreadSerialized(int id, bool serial) { assert(isPrimaryThread()); bool output = false; int status; if (serial) { // make serial // don't know if it's running or not, so try both // but try stopped state first status = SetThreadStatus( id, THREAD_STATUS_STOPPED, THREAD_STATUS_PARALLEL_TO_SERIAL_STOPPED_REQUEST ); output = output || (status == THREAD_STATUS_PARALLEL_TO_SERIAL_STOPPED_REQUEST); status = SetThreadStatus( id, THREAD_STATUS_RUNNING | THREAD_STATUS_RUNNING_REQUEST, THREAD_STATUS_PARALLEL_TO_SERIAL_RUNNING_REQUEST ); output = output || (status == THREAD_STATUS_PARALLEL_TO_SERIAL_RUNNING_REQUEST); } else { // make parallel // don't know if it's running or not, so try both // but try stopped state first status = SetThreadStatus( id, THREAD_STATUS_SERIAL_STOPPED, THREAD_STATUS_SERIAL_TO_PARALLEL_STOPPED_REQUEST ); output = output || (status == THREAD_STATUS_SERIAL_TO_PARALLEL_STOPPED_REQUEST); status = SetThreadStatus( id, THREAD_STATUS_SERIAL_RUNNING, THREAD_STATUS_SERIAL_TO_PARALLEL_RUNNING_REQUEST ); output = output || (status == THREAD_STATUS_SERIAL_TO_PARALLEL_RUNNING_REQUEST); } return output; }
//------------------------------------------------------------------------ bool ThreadManagerSerial::unassignThread(int id) { assert(isPrimaryThread()); bool output = false; // invalidate the thread // check for all states that are no longer handled by thread callback // these are states that are fundamentally serialized int status = SetThreadStatus( id, ( THREAD_STATUS_SERIAL_STOPPED | THREAD_STATUS_SERIAL_RUNNING | THREAD_STATUS_SERIAL_TO_PARALLEL_STOPPED_REQUEST | THREAD_STATUS_SERIAL_TO_PARALLEL_RUNNING_REQUEST ), THREAD_STATUS_UNASSIGNED ); output = (status == THREAD_STATUS_UNASSIGNED); if(output) { // if we unassigned the thread in a serial way, call the finalize function callFinalizeFunctionForThread(id); } else { // must not be serial, try to unassign it in a parallel way output = ThreadManager::unassignThread(id); } return output; }
//------------------------------------------------------------------------ void ThreadManagerSerial::doSerialWork() { assert(isPrimaryThread()); // iterate over threadPool and find threads running in serial // call their work and finalize functions int status; for(int i = 0; i < m_threadPoolSize; i++) { status = getThreadStatus(i); switch(status) { case THREAD_STATUS_SERIAL_RUNNING: callWorkFunctionForThread(i); break; case THREAD_STATUS_SERIAL_TO_PARALLEL_STOPPED_REQUEST: callFinalizeFunctionForThread(i); SetThreadStatus(i, THREAD_STATUS_SERIAL_TO_PARALLEL_STOPPED_REQUEST, THREAD_STATUS_STOPPED); break; case THREAD_STATUS_SERIAL_TO_PARALLEL_RUNNING_REQUEST: callFinalizeFunctionForThread(i); SetThreadStatus(i, THREAD_STATUS_SERIAL_TO_PARALLEL_RUNNING_REQUEST, THREAD_STATUS_RUNNING_REQUEST); break; default: // not in a serial state break; } } // increment the serial call count // Windows has a lightweight way to do an atomic increment InterlockedIncrement(&m_serialCalls); // yield to OS to prevent throttling yield(); }
//------------------------------------------------------------------------ void ThreadManagerSerial::callbackHandleStatus(int id, int status) { switch(status) { case THREAD_STATUS_PARALLEL_TO_SERIAL_RUNNING_REQUEST: // change to run serially // call the finalize function callFinalizeFunctionForThread(id); SetThreadStatus(id, THREAD_STATUS_PARALLEL_TO_SERIAL_RUNNING_REQUEST, THREAD_STATUS_SERIAL_RUNNING); break; case THREAD_STATUS_PARALLEL_TO_SERIAL_STOPPED_REQUEST: // change to run serially, but stopped // call the finalize function callFinalizeFunctionForThread(id); SetThreadStatus(id, THREAD_STATUS_PARALLEL_TO_SERIAL_STOPPED_REQUEST, THREAD_STATUS_SERIAL_STOPPED); break; default: // fall back on ThreadManager's implementation ThreadManager::callbackHandleStatus(id, status); break; } }
BOOL CWin32Thread::SetPriority(CGenericThread::ThreadPriority aPriority) { try { static const int iThreadPriority[]={THREAD_PRIORITY_IDLE, THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_BELOW_NORMAL, THREAD_PRIORITY_NORMAL, THREAD_PRIORITY_ABOVE_NORMAL, THREAD_PRIORITY_HIGHEST, THREAD_PRIORITY_TIME_CRITICAL}; //Do we have a thread if (GetThreadStatus()==tsStopped) { //Recreate the thread //Our thread ID DWORD dwThreadID; //Create the thread in suspend mode m_hThread=CreateThread(NULL, 0, Win32Thread, this, CREATE_SUSPENDED, &dwThreadID); //Check if created if (m_hThread) { //Set the thread ID SetThreadID(dwThreadID); //Set the status SetThreadStatus(tsSuspended); } else //Can't run return FALSE; } //Now we can set the priority return SetThreadPriority(m_hThread, iThreadPriority[aPriority]); } ERROR_HANDLER_RETURN("SetPriority",FALSE) }
BOOL CWin32Thread::Start(LPVOID pData) { try { if (GetThreadStatus()==tsStopped) { //Recreate the thread //Our thread ID DWORD dwThreadID; //Create the thread in suspend mode m_hThread=CreateThread(NULL, 0, Win32Thread, this, CREATE_SUSPENDED, &dwThreadID); //Check if created if (m_hThread) { //Set the thread ID SetThreadID(dwThreadID); //Set the status SetThreadStatus(tsSuspended); } else //Can't run return FALSE; } else if (GetThreadStatus()!=tsSuspended) return FALSE; //Start the thread CGenericThread::Start(pData); //Resume the thread if (m_hThread) if (ResumeThread(m_hThread)!=-1) //We are running return TRUE; return FALSE; } ERROR_HANDLER_RETURN("Start",FALSE) }
KOMODIA_NAMESPACE_START #define CWin32Thread_Class "CWin32Thread" CWin32Thread::CWin32Thread(LPGenericThreadProc pThreadProc) : CGenericThread(pThreadProc), m_hThread(0) { try { //Set our name SetName(CWin32Thread_Class); //Create the thread if (GetThreadProc()) { //Our thread ID DWORD dwThreadID; //Create the thread in suspend mode m_hThread=CreateThread(NULL, 0, Win32Thread, this, CREATE_SUSPENDED, &dwThreadID); //Check if created if (m_hThread) { //Set the thread ID SetThreadID(dwThreadID); //Set the status SetThreadStatus(tsSuspended); } else //An error throw std::string("Failed to create thread!"); } else //Throw the error throw std::string("No thread proc!"); } ERROR_HANDLER_RETHROW("CWin32Thread") }
BOOL CWin32Thread::Stop() { try { //Only if suspened or running //Do we have the thread ? if (m_hThread) { //What status are we if (GetThreadStatus()==tsRunning && GetBruteTermination()) //First try to close it if (!TerminateThread(m_hThread,THREAD_DO_NOTHING_EXIT_VALUE)) return FALSE; if (GetThreadStatus()==tsSuspended || GetThreadStatus()==tsRunning) if (CloseHandle(m_hThread)) { //Close the handle m_hThread=NULL; //Stopped SetThreadStatus(tsStopped); //Exit return TRUE; } else return FALSE; else { //Just close the handle if (!CloseHandle(m_hThread)) m_hThread=NULL; //Exit return FALSE; } } else return FALSE; } ERROR_HANDLER_RETURN("Stop",FALSE) }
void Debugger_Disasm::SetThreadStatusSuspend() { SetThreadStatus(THREADSTATUS_SUSPEND); }
void Debugger_Disasm::SetThreadStatusWait() { SetThreadStatus(THREADSTATUS_WAIT); }
void Debugger_Disasm::SetThreadStatusRun() { SetThreadStatus(THREADSTATUS_RUNNING); }