2014-06-20 21:56:19 +02:00
|
|
|
#include "stdafx.h"
|
|
|
|
#include "Utilities/SSemaphore.h"
|
2014-07-11 13:59:13 +02:00
|
|
|
#include "Emu/System.h"
|
2014-06-20 21:56:19 +02:00
|
|
|
|
2014-06-25 00:16:44 +02:00
|
|
|
void SSemaphore::wait()
|
2014-06-20 21:56:19 +02:00
|
|
|
{
|
2014-06-25 00:16:44 +02:00
|
|
|
u32 order;
|
|
|
|
{
|
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
2014-06-25 23:59:23 +02:00
|
|
|
if (m_count && m_out_order == m_in_order)
|
|
|
|
{
|
|
|
|
m_count--;
|
|
|
|
return;
|
|
|
|
}
|
2014-06-25 00:16:44 +02:00
|
|
|
order = m_in_order++;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::unique_lock<std::mutex> cv_lock(m_cv_mutex);
|
2014-06-20 21:56:19 +02:00
|
|
|
|
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
if (Emu.IsStopped())
|
|
|
|
{
|
2014-06-25 00:16:44 +02:00
|
|
|
return;
|
2014-06-20 21:56:19 +02:00
|
|
|
}
|
|
|
|
|
2014-06-25 23:59:23 +02:00
|
|
|
m_cond.wait_for(cv_lock, std::chrono::milliseconds(1));
|
|
|
|
|
2014-06-20 21:56:19 +02:00
|
|
|
{
|
2014-06-25 23:59:23 +02:00
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
|
|
if (m_count)
|
2014-06-25 00:16:44 +02:00
|
|
|
{
|
2014-06-25 23:59:23 +02:00
|
|
|
if (m_out_order == order)
|
|
|
|
{
|
|
|
|
m_count--;
|
|
|
|
m_out_order++;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_cond.notify_one();
|
|
|
|
}
|
2014-06-25 00:16:44 +02:00
|
|
|
}
|
2014-06-20 21:56:19 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SSemaphore::try_wait()
|
|
|
|
{
|
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
|
|
|
2014-06-25 00:16:44 +02:00
|
|
|
if (m_count && m_in_order == m_out_order)
|
2014-06-20 21:56:19 +02:00
|
|
|
{
|
|
|
|
m_count--;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-21 16:26:37 +02:00
|
|
|
void SSemaphore::post()
|
2014-06-20 21:56:19 +02:00
|
|
|
{
|
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
|
|
|
2014-06-25 23:59:23 +02:00
|
|
|
if (m_count < m_max)
|
|
|
|
{
|
|
|
|
m_count++;
|
|
|
|
}
|
|
|
|
else
|
2014-06-20 21:56:19 +02:00
|
|
|
{
|
2014-06-21 16:26:37 +02:00
|
|
|
return;
|
2014-06-20 21:56:19 +02:00
|
|
|
}
|
|
|
|
|
2014-06-21 16:26:37 +02:00
|
|
|
m_cond.notify_one();
|
2014-06-20 21:56:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool SSemaphore::post_and_wait()
|
|
|
|
{
|
2014-06-25 23:59:23 +02:00
|
|
|
// TODO: merge these functions? Probably has a race condition.
|
2014-06-20 21:56:19 +02:00
|
|
|
if (try_wait()) return false;
|
|
|
|
|
|
|
|
post();
|
|
|
|
wait();
|
|
|
|
|
|
|
|
return true;
|
2014-07-11 13:59:13 +02:00
|
|
|
}
|