Fix preprocessor prob.(recursive mutexes were being used where not necessary) Hopefully fix Common::Event to handle spurious wakeups since it uses condition variables now.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7307 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Jordan Woyak 2011-03-06 00:52:04 +00:00
parent 9601bf72df
commit 9095dad009
3 changed files with 41 additions and 4 deletions

View File

@ -99,6 +99,7 @@ public:
#elif USE_CONDITION_VARIABLES #elif USE_CONDITION_VARIABLES
SleepConditionVariableCS(m_handle, lock.mutex()->native_handle(), INFINITE); SleepConditionVariableCS(m_handle, lock.mutex()->native_handle(), INFINITE);
#else #else
// TODO: broken, the unlock and wait need to be atomic
lock.unlock(); lock.unlock();
WaitForSingleObject(m_handle, INFINITE); WaitForSingleObject(m_handle, INFINITE);
lock.lock(); lock.lock();

View File

@ -106,7 +106,7 @@ private:
native_type m_handle; native_type m_handle;
}; };
#ifdef USE_SRWLOCKS #if !defined(_WIN32) || defined(USE_SRWLOCKS)
class mutex class mutex
{ {

View File

@ -57,6 +57,7 @@ public:
void Set() void Set()
{ {
std::lock_guard<std::mutex> lk(m_mutex);
if (!is_set) if (!is_set)
{ {
is_set = true; is_set = true;
@ -68,12 +69,28 @@ public:
{ {
std::unique_lock<std::mutex> lk(m_mutex); std::unique_lock<std::mutex> lk(m_mutex);
if (!is_set) if (!is_set)
m_condvar.wait(lk); m_condvar.wait(lk, IsSet(this));
is_set = false; is_set = false;
} }
private: private:
bool is_set; class IsSet
{
public:
IsSet(const Event* ev)
: m_event(ev)
{}
bool operator()()
{
return m_event->is_set;
}
private:
const Event* const m_event;
};
volatile bool is_set;
std::condition_variable m_condvar; std::condition_variable m_condvar;
std::mutex m_mutex; std::mutex m_mutex;
}; };
@ -91,6 +108,9 @@ public:
{ {
std::unique_lock<std::mutex> lk(m_mutex); std::unique_lock<std::mutex> lk(m_mutex);
// TODO: broken when next round of Wait()s
// is entered before all waiting threads return from the notify_all
if (m_count == ++m_waiting) if (m_count == ++m_waiting)
{ {
m_waiting = 0; m_waiting = 0;
@ -99,12 +119,28 @@ public:
} }
else else
{ {
m_condvar.wait(lk); m_condvar.wait(lk, IsDoneWating(this));
return false; return false;
} }
} }
private: private:
class IsDoneWating
{
public:
IsDoneWating(const Barrier* bar)
: m_bar(bar)
{}
bool operator()()
{
return (0 == m_bar->m_waiting);
}
private:
const Barrier* const m_bar;
};
std::condition_variable m_condvar; std::condition_variable m_condvar;
std::mutex m_mutex; std::mutex m_mutex;
const size_t m_count; const size_t m_count;