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:
parent
9601bf72df
commit
9095dad009
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue