diff options
Diffstat (limited to 'Source/Core/Common/Src/Thread.cpp')
| -rw-r--r-- | Source/Core/Common/Src/Thread.cpp | 125 |
1 files changed, 124 insertions, 1 deletions
diff --git a/Source/Core/Common/Src/Thread.cpp b/Source/Core/Common/Src/Thread.cpp index efc4815cb2..a5c4e53cc6 100644 --- a/Source/Core/Common/Src/Thread.cpp +++ b/Source/Core/Common/Src/Thread.cpp @@ -15,7 +15,16 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ +#include "Setup.h" #include "Thread.h" +// ----------------------------------------- +#ifdef SETUP_TIMER_WAITING +// ----------------- + #include <windows.h> + #include "ConsoleWindow.h" + EventCallBack FunctionPointer[10]; +#endif +// ------------------------ #define THREAD_DEBUG 1 @@ -99,9 +108,18 @@ void Thread::SetCurrentThreadAffinity(int mask) } +////////////////////////////////////////////////////////////////////////////////////////// +// Regular same thread loop based waiting +// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ Event::Event() { m_hEvent = 0; + #ifdef SETUP_TIMER_WAITING + DoneWaiting = false; + StartWait = false; + hTimer = NULL; + hTimerQueue = NULL; + #endif } void Event::Init() @@ -115,22 +133,125 @@ void Event::Shutdown() m_hEvent = 0; } + + void Event::Set() { SetEvent(m_hEvent); } + void Event::Wait() { WaitForSingleObject(m_hEvent, INFINITE); } +///////////////////////////////////// + + +////////////////////////////////////////////////////////////////////////////////////////// +/* Separate thread timer based waiting, instead of same thread loop waiting. The downside with this + is that it's less convenient to use because we can't stall any threads with a loop. The positive + is that we don't cause these incredibly annoying WaitForEternity() hangings. */ +// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ +#ifdef SETUP_TIMER_WAITING +/* I could not figure out how to place this in the class to, CreateTimerQueueTimer() would complain + about some kind of type casting, anyone have any ideas about how to do it? */ +VOID CALLBACK TimerRoutine(PVOID lpParam, BOOLEAN TimerOrWaitFired) +{ + if (lpParam == NULL) + { + Console::Print("TimerRoutine lpParam is NULL\n"); + } + else + { + // lpParam points to the argument; in this case it is an int + + //Console::Print("Timer[%i] will call back\n", *(int*)lpParam); + } + + // Call back + int Id = *(int*)lpParam; + if (FunctionPointer[Id]) FunctionPointer[Id](); +} + +// Create a timer that will call back to the calling function +bool Event::TimerWait(EventCallBack WaitCB, int _Id, bool OptCondition) +{ + Id = _Id; + + //Console::Print("TimerWait[%i]: %i %i %i\n", Id, StartWait, DoneWaiting, OptCondition); + + FunctionPointer[Id] = WaitCB; + + // This means we are done waiting, so we wont call back again, and we also reset the variables for this Event + if (DoneWaiting && OptCondition) + { + StartWait = false; + DoneWaiting = false; + FunctionPointer[Id] = NULL; + + // Delete all timers in the timer queue. + if (!DeleteTimerQueue(hTimerQueue)) + Console::Print("DeleteTimerQueue failed (%d)\n", GetLastError()); + + hTimer = NULL; + hTimerQueue = NULL; + + return true; + } + + // Else start a new callback timer + StartWait = true; + + // Create the timer queue if needed + if (!hTimerQueue) + { + hTimerQueue = CreateTimerQueue(); + if (NULL == hTimerQueue) + { + Console::Print("CreateTimerQueue failed (%d)\n", GetLastError()); + return false; + } + } + + // Set a timer to call the timer routine in 10 seconds. + if (!CreateTimerQueueTimer( &hTimer, hTimerQueue, + (WAITORTIMERCALLBACK)TimerRoutine, &Id , 10, 0, 0)) + { + Console::Print("CreateTimerQueueTimer failed (%d)\n", GetLastError()); + return false; + } + + return false; +} +// Check if we are done or not +bool Event::DoneWait() +{ + if (StartWait && DoneWaiting) + return true; + else + return false; +} +// Tells the timer that we are done waiting +void Event::SetTimer() +{ + // We can not be done before we have started waiting + if (StartWait) DoneWaiting = true; +} +#endif +//////////////////////////////////////// + + + +////////////////////////////////////////////////////////////////////////////////////////// +// Supporting functions +// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ void SleepCurrentThread(int ms) { Sleep(ms); } - typedef struct tagTHREADNAME_INFO { DWORD dwType; // must be 0x1000 @@ -188,6 +309,8 @@ LONG SyncInterlockedExchange(LONG *Dest, LONG Val) { return InterlockedExchange(Dest, Val); } +//////////////////////////////////////// + #else // !WIN32, so must be POSIX threads |
