2 changed files with 0 additions and 112 deletions
@ -1,111 +0,0 @@ |
|||||
#pragma once |
|
||||
|
|
||||
// a simple lockless thread-safe, |
|
||||
// single reader, single writer queue |
|
||||
|
|
||||
#include "common/atomic.h" |
|
||||
|
|
||||
namespace Common |
|
||||
{ |
|
||||
|
|
||||
template <typename T> |
|
||||
class FifoQueue |
|
||||
{ |
|
||||
public: |
|
||||
FifoQueue() : m_size(0) |
|
||||
{ |
|
||||
m_write_ptr = m_read_ptr = new ElementPtr(); |
|
||||
} |
|
||||
|
|
||||
~FifoQueue() |
|
||||
{ |
|
||||
// this will empty out the whole queue |
|
||||
delete m_read_ptr; |
|
||||
} |
|
||||
|
|
||||
u32 Size() const |
|
||||
{ |
|
||||
return m_size; |
|
||||
} |
|
||||
|
|
||||
bool Empty() const |
|
||||
{ |
|
||||
//return (m_read_ptr == m_write_ptr); |
|
||||
return (0 == m_size); |
|
||||
} |
|
||||
|
|
||||
T& Front() const |
|
||||
{ |
|
||||
return *m_read_ptr->current; |
|
||||
} |
|
||||
|
|
||||
template <typename Arg> |
|
||||
void Push(Arg&& t) |
|
||||
{ |
|
||||
// create the element, add it to the queue |
|
||||
m_write_ptr->current = new T(std::forward<Arg>(t)); |
|
||||
// set the next pointer to a new element ptr |
|
||||
// then advance the write pointer |
|
||||
m_write_ptr = m_write_ptr->next = new ElementPtr(); |
|
||||
Common::AtomicIncrement(m_size); |
|
||||
} |
|
||||
|
|
||||
void Pop() |
|
||||
{ |
|
||||
Common::AtomicDecrement(m_size); |
|
||||
ElementPtr *const tmpptr = m_read_ptr; |
|
||||
// advance the read pointer |
|
||||
m_read_ptr = m_read_ptr->next; |
|
||||
// set the next element to NULL to stop the recursive deletion |
|
||||
tmpptr->next = nullptr; |
|
||||
delete tmpptr; // this also deletes the element |
|
||||
} |
|
||||
|
|
||||
bool Pop(T& t) |
|
||||
{ |
|
||||
if (Empty()) |
|
||||
return false; |
|
||||
|
|
||||
t = std::move(Front()); |
|
||||
Pop(); |
|
||||
|
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
// not thread-safe |
|
||||
void Clear() |
|
||||
{ |
|
||||
m_size = 0; |
|
||||
delete m_read_ptr; |
|
||||
m_write_ptr = m_read_ptr = new ElementPtr(); |
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
// stores a pointer to element |
|
||||
// and a pointer to the next ElementPtr |
|
||||
class ElementPtr |
|
||||
{ |
|
||||
public: |
|
||||
ElementPtr() : current(nullptr), next(nullptr) {} |
|
||||
|
|
||||
~ElementPtr() |
|
||||
{ |
|
||||
if (current) |
|
||||
{ |
|
||||
delete current; |
|
||||
// recusion ftw |
|
||||
if (next) |
|
||||
delete next; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
T *volatile current; |
|
||||
ElementPtr *volatile next; |
|
||||
}; |
|
||||
|
|
||||
ElementPtr *volatile m_write_ptr; |
|
||||
ElementPtr *volatile m_read_ptr; |
|
||||
volatile u32 m_size; |
|
||||
}; |
|
||||
|
|
||||
} |
|
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue