1 /*
2  * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
3  * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
4  */
5 
6 #ifndef BX_SPSCQUEUE_H_HEADER_GUARD
7 #define BX_SPSCQUEUE_H_HEADER_GUARD
8 
9 #include "allocator.h"
10 #include "cpu.h"
11 #include "semaphore.h"
12 
13 namespace bx
14 {
15 	///
16 	class SpScUnboundedQueue
17 	{
18 		BX_CLASS(SpScUnboundedQueue
19 			, NO_COPY
20 			, NO_ASSIGNMENT
21 			);
22 
23 	public:
24 		///
25 		SpScUnboundedQueue(AllocatorI* _allocator);
26 
27 		///
28 		~SpScUnboundedQueue();
29 
30 		///
31 		void push(void* _ptr);
32 
33 		///
34 		void* peek();
35 
36 		///
37 		void* pop();
38 
39 	private:
40 		struct Node
41 		{
42 			///
43 			Node(void* _ptr);
44 
45 			void* m_ptr;
46 			Node* m_next;
47 		};
48 
49 		AllocatorI* m_allocator;
50 		Node* m_first;
51 		Node* m_divider;
52 		Node* m_last;
53 	};
54 
55 	///
56 	template<typename Ty>
57 	class SpScUnboundedQueueT
58 	{
59 		BX_CLASS(SpScUnboundedQueueT
60 			, NO_COPY
61 			, NO_ASSIGNMENT
62 			);
63 
64 	public:
65 		///
66 		SpScUnboundedQueueT(AllocatorI* _allocator);
67 
68 		///
69 		~SpScUnboundedQueueT();
70 
71 		///
72 		void push(Ty* _ptr);
73 
74 		///
75 		Ty* peek();
76 
77 		///
78 		Ty* pop();
79 
80 	private:
81 		SpScUnboundedQueue m_queue;
82 	};
83 
84 #if BX_CONFIG_SUPPORTS_THREADING
85 	///
86 	class SpScBlockingUnboundedQueue
87 	{
88 		BX_CLASS(SpScBlockingUnboundedQueue
89 			, NO_COPY
90 			, NO_ASSIGNMENT
91 			);
92 
93 	public:
94 		///
95 		SpScBlockingUnboundedQueue(AllocatorI* _allocator);
96 
97 		///
98 		~SpScBlockingUnboundedQueue();
99 
100 		///
101 		void push(void* _ptr); // producer only
102 
103 		///
104 		void* peek(); // consumer only
105 
106 		///
107 		void* pop(int32_t _msecs = -1); // consumer only
108 
109 	private:
110 		Semaphore m_count;
111 		SpScUnboundedQueue m_queue;
112 	};
113 
114 	///
115 	template<typename Ty>
116 	class SpScBlockingUnboundedQueueT
117 	{
118 		BX_CLASS(SpScBlockingUnboundedQueueT
119 			, NO_COPY
120 			, NO_ASSIGNMENT
121 			);
122 
123 	public:
124 		///
125 		SpScBlockingUnboundedQueueT(AllocatorI* _allocator);
126 
127 		///
128 		~SpScBlockingUnboundedQueueT();
129 
130 		///
131 		void push(Ty* _ptr); // producer only
132 
133 		///
134 		Ty* peek(); // consumer only
135 
136 		///
137 		Ty* pop(int32_t _msecs = -1); // consumer only
138 
139 	private:
140 		SpScBlockingUnboundedQueue m_queue;
141 	};
142 #endif // BX_CONFIG_SUPPORTS_THREADING
143 
144 } // namespace bx
145 
146 #include "inline/spscqueue.inl"
147 
148 #endif // BX_SPSCQUEUE_H_HEADER_GUARD
149