|
|
@@ -8,14 +8,11 @@
|
|
|
|
|
|
#include "bx.h"
|
|
|
#include "cpu.h"
|
|
|
-#include "mutex.h"
|
|
|
#include "semaphore.h"
|
|
|
-#include "uint32_t.h"
|
|
|
|
|
|
namespace bx
|
|
|
{
|
|
|
- // http://drdobbs.com/article/print?articleId=210604448&siteSectionName=
|
|
|
- template <typename Ty>
|
|
|
+ ///
|
|
|
class SpScUnboundedQueue
|
|
|
{
|
|
|
BX_CLASS(SpScUnboundedQueue
|
|
|
@@ -24,66 +21,26 @@ namespace bx
|
|
|
);
|
|
|
|
|
|
public:
|
|
|
- SpScUnboundedQueue()
|
|
|
- : m_first(new Node(NULL) )
|
|
|
- , m_divider(m_first)
|
|
|
- , m_last(m_first)
|
|
|
- {
|
|
|
- }
|
|
|
+ ///
|
|
|
+ SpScUnboundedQueue();
|
|
|
|
|
|
- ~SpScUnboundedQueue()
|
|
|
- {
|
|
|
- while (NULL != m_first)
|
|
|
- {
|
|
|
- Node* node = m_first;
|
|
|
- m_first = node->m_next;
|
|
|
- delete node;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- void push(Ty* _ptr) // producer only
|
|
|
- {
|
|
|
- m_last->m_next = new Node( (void*)_ptr);
|
|
|
- atomicExchangePtr( (void**)&m_last, m_last->m_next);
|
|
|
- while (m_first != m_divider)
|
|
|
- {
|
|
|
- Node* node = m_first;
|
|
|
- m_first = m_first->m_next;
|
|
|
- delete node;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- Ty* peek() // consumer only
|
|
|
- {
|
|
|
- if (m_divider != m_last)
|
|
|
- {
|
|
|
- Ty* ptr = (Ty*)m_divider->m_next->m_ptr;
|
|
|
- return ptr;
|
|
|
- }
|
|
|
+ ///
|
|
|
+ ~SpScUnboundedQueue();
|
|
|
|
|
|
- return NULL;
|
|
|
- }
|
|
|
+ ///
|
|
|
+ void push(void* _ptr);
|
|
|
|
|
|
- Ty* pop() // consumer only
|
|
|
- {
|
|
|
- if (m_divider != m_last)
|
|
|
- {
|
|
|
- Ty* ptr = (Ty*)m_divider->m_next->m_ptr;
|
|
|
- atomicExchangePtr( (void**)&m_divider, m_divider->m_next);
|
|
|
- return ptr;
|
|
|
- }
|
|
|
+ ///
|
|
|
+ void* peek();
|
|
|
|
|
|
- return NULL;
|
|
|
- }
|
|
|
+ ///
|
|
|
+ void* pop();
|
|
|
|
|
|
private:
|
|
|
struct Node
|
|
|
{
|
|
|
- Node(void* _ptr)
|
|
|
- : m_ptr(_ptr)
|
|
|
- , m_next(NULL)
|
|
|
- {
|
|
|
- }
|
|
|
+ ///
|
|
|
+ Node(void* _ptr);
|
|
|
|
|
|
void* m_ptr;
|
|
|
Node* m_next;
|
|
|
@@ -94,8 +51,38 @@ namespace bx
|
|
|
Node* m_last;
|
|
|
};
|
|
|
|
|
|
+ ///
|
|
|
+ template<typename Ty>
|
|
|
+ class SpScUnboundedQueueT
|
|
|
+ {
|
|
|
+ BX_CLASS(SpScUnboundedQueueT
|
|
|
+ , NO_COPY
|
|
|
+ , NO_ASSIGNMENT
|
|
|
+ );
|
|
|
+
|
|
|
+ public:
|
|
|
+ ///
|
|
|
+ SpScUnboundedQueueT();
|
|
|
+
|
|
|
+ ///
|
|
|
+ ~SpScUnboundedQueueT();
|
|
|
+
|
|
|
+ ///
|
|
|
+ void push(Ty* _ptr);
|
|
|
+
|
|
|
+ ///
|
|
|
+ Ty* peek();
|
|
|
+
|
|
|
+ ///
|
|
|
+ Ty* pop();
|
|
|
+
|
|
|
+ private:
|
|
|
+ SpScUnboundedQueue m_queue;
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
#if BX_CONFIG_SUPPORTS_THREADING
|
|
|
- template <typename Ty>
|
|
|
+ ///
|
|
|
class SpScBlockingUnboundedQueue
|
|
|
{
|
|
|
BX_CLASS(SpScBlockingUnboundedQueue
|
|
|
@@ -104,41 +91,58 @@ namespace bx
|
|
|
);
|
|
|
|
|
|
public:
|
|
|
- SpScBlockingUnboundedQueue()
|
|
|
- {
|
|
|
- }
|
|
|
+ ///
|
|
|
+ SpScBlockingUnboundedQueue();
|
|
|
|
|
|
- ~SpScBlockingUnboundedQueue()
|
|
|
- {
|
|
|
- }
|
|
|
+ ///
|
|
|
+ ~SpScBlockingUnboundedQueue();
|
|
|
|
|
|
- void push(Ty* _ptr) // producer only
|
|
|
- {
|
|
|
- m_queue.push( (void*)_ptr);
|
|
|
- m_count.post();
|
|
|
- }
|
|
|
+ ///
|
|
|
+ void push(void* _ptr); // producer only
|
|
|
|
|
|
- Ty* peek() // consumer only
|
|
|
- {
|
|
|
- return (Ty*)m_queue.peek();
|
|
|
- }
|
|
|
-
|
|
|
- Ty* pop(int32_t _msecs = -1) // consumer only
|
|
|
- {
|
|
|
- if (m_count.wait(_msecs) )
|
|
|
- {
|
|
|
- return (Ty*)m_queue.pop();
|
|
|
- }
|
|
|
+ ///
|
|
|
+ void* peek(); // consumer only
|
|
|
|
|
|
- return NULL;
|
|
|
- }
|
|
|
+ ///
|
|
|
+ void* pop(int32_t _msecs = -1); // consumer only
|
|
|
|
|
|
private:
|
|
|
Semaphore m_count;
|
|
|
- SpScUnboundedQueue<void> m_queue;
|
|
|
+ SpScUnboundedQueue m_queue;
|
|
|
+ };
|
|
|
+
|
|
|
+ ///
|
|
|
+ template<typename Ty>
|
|
|
+ class SpScBlockingUnboundedQueueT
|
|
|
+ {
|
|
|
+ BX_CLASS(SpScBlockingUnboundedQueueT
|
|
|
+ , NO_COPY
|
|
|
+ , NO_ASSIGNMENT
|
|
|
+ );
|
|
|
+
|
|
|
+ public:
|
|
|
+ ///
|
|
|
+ SpScBlockingUnboundedQueueT();
|
|
|
+
|
|
|
+ ///
|
|
|
+ ~SpScBlockingUnboundedQueueT();
|
|
|
+
|
|
|
+ ///
|
|
|
+ void push(Ty* _ptr); // producer only
|
|
|
+
|
|
|
+ ///
|
|
|
+ Ty* peek(); // consumer only
|
|
|
+
|
|
|
+ ///
|
|
|
+ Ty* pop(int32_t _msecs = -1); // consumer only
|
|
|
+
|
|
|
+ private:
|
|
|
+ SpScBlockingUnboundedQueue m_queue;
|
|
|
};
|
|
|
#endif // BX_CONFIG_SUPPORTS_THREADING
|
|
|
|
|
|
} // namespace bx
|
|
|
|
|
|
+#include "spscqueue.inl"
|
|
|
+
|
|
|
#endif // BX_SPSCQUEUE_H_HEADER_GUARD
|