summaryrefslogtreecommitdiff
path: root/Source/Core/Common/Src/Thread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/Common/Src/Thread.cpp')
-rw-r--r--Source/Core/Common/Src/Thread.cpp125
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