mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-22 05:40:01 -06:00
This could alleviate the suffering of dual core synchronization a bit.
But I doubt you would notice it in most cases. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4830 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@ -117,6 +117,60 @@ void Thread::SetCurrentThreadAffinity(int mask)
|
||||
SetThreadAffinityMask(GetCurrentThread(), mask);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
EventEx::EventEx()
|
||||
{
|
||||
InterlockedExchange(&m_Lock, 1);
|
||||
}
|
||||
|
||||
void EventEx::Init()
|
||||
{
|
||||
InterlockedExchange(&m_Lock, 1);
|
||||
}
|
||||
|
||||
void EventEx::Shutdown()
|
||||
{
|
||||
InterlockedExchange(&m_Lock, 0);
|
||||
}
|
||||
|
||||
void EventEx::Set()
|
||||
{
|
||||
InterlockedExchange(&m_Lock, 0);
|
||||
}
|
||||
|
||||
void EventEx::Spin()
|
||||
{
|
||||
while (InterlockedCompareExchange(&m_Lock, 1, 0))
|
||||
// This only yields when there is a runnable thread on this core
|
||||
// If not, spin
|
||||
SwitchToThread();
|
||||
}
|
||||
|
||||
void EventEx::Wait()
|
||||
{
|
||||
while (InterlockedCompareExchange(&m_Lock, 1, 0))
|
||||
// This directly enters Ring0 and enforces a sleep about 15ms
|
||||
SleepCurrentThread(1);
|
||||
}
|
||||
|
||||
bool EventEx::MsgWait()
|
||||
{
|
||||
while (InterlockedCompareExchange(&m_Lock, 1, 0))
|
||||
{
|
||||
MSG msg;
|
||||
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
|
||||
{
|
||||
if (msg.message == WM_QUIT) return false;
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
// This directly enters Ring0 and enforces a sleep about 15ms
|
||||
SleepCurrentThread(1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Regular same thread loop based waiting
|
||||
Event::Event()
|
||||
{
|
||||
@ -164,6 +218,7 @@ void Event::MsgWait()
|
||||
if (msg.message == WM_QUIT)
|
||||
return;
|
||||
// Otherwise, dispatch the message.
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,31 @@ private:
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
// Event(WaitForSingleObject) is too expensive
|
||||
// as it always enters Ring0 regardless of the state of lock
|
||||
// This EventEx will try to stay in Ring3 as much as possible
|
||||
// If the lock can be obtained in the first time, Ring0 won't be entered at all
|
||||
class EventEx
|
||||
{
|
||||
public:
|
||||
EventEx();
|
||||
void Init();
|
||||
void Shutdown();
|
||||
void Set();
|
||||
// Infinite wait
|
||||
void Spin();
|
||||
// Infinite wait with sleep
|
||||
void Wait();
|
||||
// Wait with message processing and sleep
|
||||
bool MsgWait();
|
||||
private:
|
||||
volatile long m_Lock;
|
||||
};
|
||||
#else
|
||||
// TODO: implement for Linux
|
||||
#define EventEx Event
|
||||
#endif
|
||||
|
||||
class Event
|
||||
{
|
||||
@ -182,9 +206,10 @@ private:
|
||||
void InitThreading();
|
||||
void SleepCurrentThread(int ms);
|
||||
|
||||
// YieldCPU: Use this function during a spin-wait to make the current thread
|
||||
// relax while another thread is working. This may be more efficient than using
|
||||
// events because event functions use kernel calls.
|
||||
// YieldCPU: This function is only effective on HyperThreading CPU
|
||||
// Use this function during a spin-wait to make the current thread
|
||||
// relax while another thread is working. This may be more efficient
|
||||
// than using events because event functions use kernel calls.
|
||||
inline void YieldCPU()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
Reference in New Issue
Block a user