| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- #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;
- };
- }
|