SQueue little improvement

This commit is contained in:
Nekotekina 2014-06-20 23:57:28 +04:00
parent 1c4ae999d6
commit e79236a97f

View File

@ -4,6 +4,8 @@ template<typename T, u32 SQSize = 666>
class SQueue class SQueue
{ {
std::mutex m_mutex; std::mutex m_mutex;
NamedThreadBase* push_waiter;
NamedThreadBase* pop_waiter;
u32 m_pos; u32 m_pos;
u32 m_count; u32 m_count;
T m_data[SQSize]; T m_data[SQSize];
@ -12,6 +14,8 @@ public:
SQueue() SQueue()
: m_pos(0) : m_pos(0)
, m_count(0) , m_count(0)
, push_waiter(nullptr)
, pop_waiter(nullptr)
{ {
} }
@ -22,6 +26,9 @@ public:
bool Push(const T& data) bool Push(const T& data)
{ {
NamedThreadBase* t = GetCurrentNamedThread();
push_waiter = t;
while (true) while (true)
{ {
if (m_count >= SQSize) if (m_count >= SQSize)
@ -30,7 +37,8 @@ public:
{ {
return false; return false;
} }
Sleep(1);
SM_Sleep();
continue; continue;
} }
@ -38,9 +46,11 @@ public:
std::lock_guard<std::mutex> lock(m_mutex); std::lock_guard<std::mutex> lock(m_mutex);
if (m_count >= SQSize) continue; if (m_count >= SQSize) continue;
if (pop_waiter && !m_count) pop_waiter->Notify();
m_data[(m_pos + m_count++) % SQSize] = data; m_data[(m_pos + m_count++) % SQSize] = data;
push_waiter = nullptr;
return true; return true;
} }
} }
@ -48,6 +58,9 @@ public:
bool Pop(T& data) bool Pop(T& data)
{ {
NamedThreadBase* t = GetCurrentNamedThread();
pop_waiter = t;
while (true) while (true)
{ {
if (!m_count) if (!m_count)
@ -56,7 +69,8 @@ public:
{ {
return false; return false;
} }
Sleep(1);
SM_Sleep();
continue; continue;
} }
@ -64,22 +78,24 @@ public:
std::lock_guard<std::mutex> lock(m_mutex); std::lock_guard<std::mutex> lock(m_mutex);
if (!m_count) continue; if (!m_count) continue;
if (push_waiter && m_count >= SQSize) push_waiter->Notify();
data = m_data[m_pos]; data = m_data[m_pos];
m_pos = (m_pos + 1) % SQSize; m_pos = (m_pos + 1) % SQSize;
m_count--; m_count--;
pop_waiter = nullptr;
return true; return true;
} }
} }
} }
volatile u32 GetCount() // may be not safe volatile u32 GetCount() // may be thread unsafe
{ {
return m_count; return m_count;
} }
volatile bool IsEmpty() // may be not safe volatile bool IsEmpty() // may be thread unsafe
{ {
return !m_count; return !m_count;
} }
@ -87,11 +103,15 @@ public:
void Clear() void Clear()
{ {
std::lock_guard<std::mutex> lock(m_mutex); std::lock_guard<std::mutex> lock(m_mutex);
if (push_waiter && m_count >= SQSize) push_waiter->Notify();
m_count = 0; m_count = 0;
} }
T& Peek(u32 pos = 0) T& Peek(u32 pos = 0)
{ {
NamedThreadBase* t = GetCurrentNamedThread();
pop_waiter = t;
while (true) while (true)
{ {
if (!m_count) if (!m_count)
@ -100,13 +120,18 @@ public:
{ {
break; break;
} }
Sleep(1);
SM_Sleep();
continue; continue;
} }
{ {
std::lock_guard<std::mutex> lock(m_mutex); std::lock_guard<std::mutex> lock(m_mutex);
if (m_count) break; if (m_count)
{
pop_waiter = nullptr;
break;
}
} }
} }
return m_data[(m_pos + pos) % SQSize]; return m_data[(m_pos + pos) % SQSize];