2014-02-24 01:00:42 +01:00
|
|
|
#pragma once
|
|
|
|
|
2014-08-23 16:51:51 +02:00
|
|
|
#include "Utilities/SMutex.h"
|
|
|
|
|
2014-02-24 01:00:42 +01:00
|
|
|
template<typename T, u32 SQSize = 666>
|
|
|
|
class SQueue
|
|
|
|
{
|
2014-06-20 13:00:36 +02:00
|
|
|
std::mutex m_mutex;
|
2014-02-24 01:00:42 +01:00
|
|
|
u32 m_pos;
|
|
|
|
u32 m_count;
|
|
|
|
T m_data[SQSize];
|
|
|
|
|
|
|
|
public:
|
|
|
|
SQueue()
|
|
|
|
: m_pos(0)
|
|
|
|
, m_count(0)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-03-31 12:04:34 +02:00
|
|
|
const u32 GetSize() const
|
|
|
|
{
|
|
|
|
return SQSize;
|
|
|
|
}
|
|
|
|
|
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_count >= SQSize)
|
|
|
|
{
|
2014-03-03 00:02:42 +01:00
|
|
|
if (Emu.IsStopped())
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2014-06-20 21:57:28 +02:00
|
|
|
|
|
|
|
SM_Sleep();
|
2014-02-24 01:00:42 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
2014-06-20 13:00:36 +02:00
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
2014-02-24 01:00:42 +01:00
|
|
|
|
|
|
|
if (m_count >= SQSize) continue;
|
|
|
|
|
|
|
|
m_data[(m_pos + m_count++) % SQSize] = data;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Pop(T& data)
|
|
|
|
{
|
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
if (!m_count)
|
|
|
|
{
|
2014-03-03 00:02:42 +01:00
|
|
|
if (Emu.IsStopped())
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2014-06-20 21:57:28 +02:00
|
|
|
|
|
|
|
SM_Sleep();
|
2014-02-24 01:00:42 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
2014-06-20 13:00:36 +02:00
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
2014-02-24 01:00:42 +01:00
|
|
|
|
|
|
|
if (!m_count) continue;
|
|
|
|
|
|
|
|
data = m_data[m_pos];
|
|
|
|
m_pos = (m_pos + 1) % SQSize;
|
|
|
|
m_count--;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-29 05:21:57 +02:00
|
|
|
u32 GetCount()
|
2014-02-24 01:00:42 +01:00
|
|
|
{
|
2014-06-29 05:21:57 +02:00
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
2014-02-24 01:00:42 +01:00
|
|
|
return m_count;
|
|
|
|
}
|
|
|
|
|
2014-06-29 05:21:57 +02:00
|
|
|
u32 GetCountUnsafe()
|
2014-02-24 01:00:42 +01:00
|
|
|
{
|
2014-06-29 05:21:57 +02:00
|
|
|
return m_count;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IsEmpty()
|
|
|
|
{
|
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
2014-02-24 01:00:42 +01:00
|
|
|
return !m_count;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Clear()
|
|
|
|
{
|
2014-06-20 13:00:36 +02:00
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
2014-02-24 01:00:42 +01:00
|
|
|
m_count = 0;
|
|
|
|
}
|
2014-03-03 00:02:42 +01:00
|
|
|
|
|
|
|
T& Peek(u32 pos = 0)
|
|
|
|
{
|
2014-03-22 02:08:25 +01:00
|
|
|
while (true)
|
|
|
|
{
|
2014-06-29 05:21:57 +02:00
|
|
|
if (m_count <= pos)
|
2014-03-22 02:08:25 +01:00
|
|
|
{
|
|
|
|
if (Emu.IsStopped())
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
2014-06-20 21:57:28 +02:00
|
|
|
|
|
|
|
SM_Sleep();
|
2014-03-22 02:08:25 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
2014-06-20 13:00:36 +02:00
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
2014-06-29 05:21:57 +02:00
|
|
|
if (m_count > pos)
|
2014-06-20 21:57:28 +02:00
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
2014-03-22 02:08:25 +01:00
|
|
|
}
|
|
|
|
}
|
2014-03-03 00:02:42 +01:00
|
|
|
return m_data[(m_pos + pos) % SQSize];
|
|
|
|
}
|
2014-06-29 05:21:57 +02:00
|
|
|
|
2014-07-01 18:04:58 +02:00
|
|
|
T& PeekIfExist(u32 pos = 0)
|
2014-06-29 05:21:57 +02:00
|
|
|
{
|
2014-07-01 18:04:58 +02:00
|
|
|
static T def_value;
|
|
|
|
|
2014-06-29 05:21:57 +02:00
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
|
|
if (m_count <= pos)
|
|
|
|
{
|
2014-07-01 18:04:58 +02:00
|
|
|
return def_value;
|
2014-06-29 05:21:57 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return m_data[(m_pos + pos) % SQSize];
|
|
|
|
}
|
|
|
|
}
|
2014-03-06 12:50:45 +01:00
|
|
|
};
|