1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-26 04:32:35 +01:00
rpcs3/Utilities/SSemaphore.cpp

89 lines
1.1 KiB
C++
Raw Normal View History

#include "stdafx.h"
#include "Utilities/SSemaphore.h"
2014-07-11 13:59:13 +02:00
#include "Emu/System.h"
2014-06-25 00:16:44 +02:00
void SSemaphore::wait()
{
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);
while (true)
{
if (Emu.IsStopped())
{
2014-06-25 00:16:44 +02:00
return;
}
2014-06-25 23:59:23 +02:00
m_cond.wait_for(cv_lock, std::chrono::milliseconds(1));
{
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
}
}
}
}
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)
{
m_count--;
return true;
}
else
{
return false;
}
}
2014-06-21 16:26:37 +02:00
void SSemaphore::post()
{
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-21 16:26:37 +02:00
return;
}
2014-06-21 16:26:37 +02:00
m_cond.notify_one();
}
bool SSemaphore::post_and_wait()
{
2014-06-25 23:59:23 +02:00
// TODO: merge these functions? Probably has a race condition.
if (try_wait()) return false;
post();
wait();
return true;
2014-07-11 13:59:13 +02:00
}