spscqueue.inl 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
  3. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
  4. */
  5. #ifndef BX_SPSCQUEUE_H_HEADER_GUARD
  6. # error "Must be included from bx/spscqueue.h!"
  7. #endif // BX_SPSCQUEUE_H_HEADER_GUARD
  8. namespace bx
  9. {
  10. // http://drdobbs.com/article/print?articleId=210604448&siteSectionName=
  11. inline SpScUnboundedQueue::SpScUnboundedQueue(AllocatorI* _allocator)
  12. : m_allocator(_allocator)
  13. , m_first(BX_NEW(m_allocator, Node)(NULL) )
  14. , m_divider(m_first)
  15. , m_last(m_first)
  16. {
  17. }
  18. inline SpScUnboundedQueue::~SpScUnboundedQueue()
  19. {
  20. while (NULL != m_first)
  21. {
  22. Node* node = m_first;
  23. m_first = node->m_next;
  24. BX_DELETE(m_allocator, node);
  25. }
  26. }
  27. inline void SpScUnboundedQueue::push(void* _ptr)
  28. {
  29. m_last->m_next = BX_NEW(m_allocator, Node)(_ptr);
  30. atomicExchangePtr( (void**)&m_last, m_last->m_next);
  31. while (m_first != m_divider)
  32. {
  33. Node* node = m_first;
  34. m_first = m_first->m_next;
  35. BX_DELETE(m_allocator, node);
  36. }
  37. }
  38. inline void* SpScUnboundedQueue::peek()
  39. {
  40. if (m_divider != m_last)
  41. {
  42. return m_divider->m_next->m_ptr;
  43. }
  44. return NULL;
  45. }
  46. inline void* SpScUnboundedQueue::pop()
  47. {
  48. if (m_divider != m_last)
  49. {
  50. void* ptr = m_divider->m_next->m_ptr;
  51. atomicExchangePtr( (void**)&m_divider, m_divider->m_next);
  52. return ptr;
  53. }
  54. return NULL;
  55. }
  56. inline SpScUnboundedQueue::Node::Node(void* _ptr)
  57. : m_ptr(_ptr)
  58. , m_next(NULL)
  59. {
  60. }
  61. template<typename Ty>
  62. inline SpScUnboundedQueueT<Ty>::SpScUnboundedQueueT(AllocatorI* _allocator)
  63. : m_queue(_allocator)
  64. {
  65. }
  66. template<typename Ty>
  67. inline SpScUnboundedQueueT<Ty>::~SpScUnboundedQueueT()
  68. {
  69. }
  70. template<typename Ty>
  71. inline void SpScUnboundedQueueT<Ty>::push(Ty* _ptr)
  72. {
  73. m_queue.push(_ptr);
  74. }
  75. template<typename Ty>
  76. inline Ty* SpScUnboundedQueueT<Ty>::peek()
  77. {
  78. return (Ty*)m_queue.peek();
  79. }
  80. template<typename Ty>
  81. inline Ty* SpScUnboundedQueueT<Ty>::pop()
  82. {
  83. return (Ty*)m_queue.pop();
  84. }
  85. #if BX_CONFIG_SUPPORTS_THREADING
  86. inline SpScBlockingUnboundedQueue::SpScBlockingUnboundedQueue(AllocatorI* _allocator)
  87. : m_queue(_allocator)
  88. {
  89. }
  90. inline SpScBlockingUnboundedQueue::~SpScBlockingUnboundedQueue()
  91. {
  92. }
  93. inline void SpScBlockingUnboundedQueue::push(void* _ptr)
  94. {
  95. m_queue.push(_ptr);
  96. m_count.post();
  97. }
  98. inline void* SpScBlockingUnboundedQueue::peek()
  99. {
  100. return m_queue.peek();
  101. }
  102. inline void* SpScBlockingUnboundedQueue::pop(int32_t _msecs)
  103. {
  104. if (m_count.wait(_msecs) )
  105. {
  106. return m_queue.pop();
  107. }
  108. return NULL;
  109. }
  110. template<typename Ty>
  111. inline SpScBlockingUnboundedQueueT<Ty>::SpScBlockingUnboundedQueueT(AllocatorI* _allocator)
  112. : m_queue(_allocator)
  113. {
  114. }
  115. template<typename Ty>
  116. inline SpScBlockingUnboundedQueueT<Ty>::~SpScBlockingUnboundedQueueT()
  117. {
  118. }
  119. template<typename Ty>
  120. inline void SpScBlockingUnboundedQueueT<Ty>::push(Ty* _ptr)
  121. {
  122. m_queue.push(_ptr);
  123. }
  124. template<typename Ty>
  125. inline Ty* SpScBlockingUnboundedQueueT<Ty>::peek()
  126. {
  127. return (Ty*)m_queue.peek();
  128. }
  129. template<typename Ty>
  130. inline Ty* SpScBlockingUnboundedQueueT<Ty>::pop(int32_t _msecs)
  131. {
  132. return (Ty*)m_queue.pop(_msecs);
  133. }
  134. #endif // BX_CONFIG_SUPPORTS_THREADING
  135. } // namespace bx