1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 18:53:28 +01:00
rpcs3/Utilities/SQueue.h

104 lines
1.2 KiB
C
Raw Normal View History

2014-02-24 01:00:42 +01:00
#pragma once
template<typename T, u32 SQSize = 666>
class SQueue
{
SMutex m_mutex;
u32 m_pos;
u32 m_count;
T m_data[SQSize];
public:
SQueue()
: m_pos(0)
, m_count(0)
{
}
2014-03-06 12:50:45 +01:00
bool Push(const T& data)
2014-02-24 01:00:42 +01:00
{
while (true)
{
if (m_mutex.GetOwner() == m_mutex.GetDeadValue())
{
return false;
}
if (m_count >= SQSize)
{
2014-03-03 00:02:42 +01:00
if (Emu.IsStopped())
{
return false;
}
2014-02-24 01:00:42 +01:00
Sleep(1);
continue;
}
{
SMutexLocker lock(m_mutex);
if (m_count >= SQSize) continue;
m_data[(m_pos + m_count++) % SQSize] = data;
return true;
}
}
}
bool Pop(T& data)
{
while (true)
{
if (m_mutex.GetOwner() == m_mutex.GetDeadValue())
{
return false;
}
if (!m_count)
{
2014-03-03 00:02:42 +01:00
if (Emu.IsStopped())
{
return false;
}
2014-02-24 01:00:42 +01:00
Sleep(1);
continue;
}
{
SMutexLocker lock(m_mutex);
if (!m_count) continue;
data = m_data[m_pos];
m_pos = (m_pos + 1) % SQSize;
m_count--;
return true;
}
}
}
volatile u32 GetCount()
2014-02-24 01:00:42 +01:00
{
return m_count;
}
volatile bool IsEmpty()
2014-02-24 01:00:42 +01:00
{
return !m_count;
}
void Clear()
{
SMutexLocker lock(m_mutex);
m_count = 0;
}
2014-03-03 00:02:42 +01:00
T& Peek(u32 pos = 0)
{
SMutexLocker lock(m_mutex);
return m_data[(m_pos + pos) % SQSize];
}
2014-03-06 12:50:45 +01:00
};