1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     os_BlockingQueue.h
4 
5   Copyright (C)2009 Nintendo Co., Ltd.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law. They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Rev: 33107 $
14  *---------------------------------------------------------------------------*/
15 
16 /* Please see man pages for details
17 
18 
19 
20 
21 */
22 
23 #ifndef NN_OS_OS_INTERCORE_BLOCKINGQUEUE_H_
24 #define NN_OS_OS_INTERCORE_BLOCKINGQUEUE_H_
25 
26 #include <nn/os/os_InterCoreLightSemaphore.h>
27 #include <nn/os/os_InterCoreCriticalSection.h>
28 #include <nn/fnd/fnd_Interlocked.h>
29 #include <nn/util/util_NonCopyable.h>
30 
31 #ifdef __cplusplus
32 
33 namespace nn { namespace os {
34 
35 namespace detail {
36 
37 /* Please see man pages for details
38 
39 
40 
41 */
42 template <class Locker>
43 class InterCoreBlockingQueueBase : private nn::util::NonCopyable<InterCoreBlockingQueueBase<Locker> >
44 {
45 protected:
InterCoreBlockingQueueBase()46     InterCoreBlockingQueueBase() {}
InterCoreBlockingQueueBase(uptr buffer[],size_t size)47     InterCoreBlockingQueueBase(uptr buffer[], size_t size) { Initialize(buffer, size); }
48     ~InterCoreBlockingQueueBase();
49     void Initialize(uptr buffer[], size_t size);
50     nn::Result TryInitialize(uptr buffer[], size_t size);
51     void Finalize();
52     void Enqueue(uptr data);
53     bool TryEnqueue(uptr data);
54     bool ForceEnqueue(uptr data, uptr* pOut);
55     void Jam(uptr data);
56     bool TryJam(uptr data);
57     uptr Dequeue();
58     bool TryDequeue(uptr* pOut);
59     uptr GetFront() const;
60     bool TryGetFront(uptr* pOut) const;
61 
62     // TODO: Decide how to handle these functions
63 
GetWaitingEnqueueCount(void)64     s32 GetWaitingEnqueueCount(void) const
65         { return m_WaitingEnqueueCount; }
66 
GetWaitingDequeueCount(void)67     s32 GetWaitingDequeueCount(void) const
68         { return m_WaitingDequeueCount; }
69 
70     // Internal member accessor for test purposes
GetSize()71     s32 GetSize() const
72         { return m_size; }
73 
GetUsedCount()74     s32 GetUsedCount() const
75         { return m_usedCount; }
76 
GetFirstIndex()77     s32 GetFirstIndex() const
78         { return m_firstIndex; }
79 
80 private:
81     typedef typename Locker::ScopedLock ScopedLock;
82 
83     uptr*                   m_ppBuffer;			//
84     mutable InterCoreLightSemaphore  m_EnqueueSemaphore; //
85     mutable InterCoreLightSemaphore  m_DequeueSemaphore; //
86     mutable Locker          m_cs;				//
87     size_t                  m_size;             //
88     s32                     m_firstIndex;       //
89     s32                     m_usedCount;        //
90     mutable nn::fnd::InterlockedVariable<s32> m_WaitingEnqueueCount; //
91     mutable nn::fnd::InterlockedVariable<s32> m_WaitingDequeueCount; //
92 
93 	//
94     void NotifyEnqueue() const;
95 
96 	//
97     void NotifyDequeue() const;
98 };
99 
100 }
101 
102 
103 /* Please see man pages for details
104 
105 
106 
107 
108 */
109 class InterCoreBlockingQueue : private os::detail::InterCoreBlockingQueueBase<nn::os::InterCoreCriticalSection>
110 {
111 private:
112     typedef os::detail::InterCoreBlockingQueueBase<nn::os::InterCoreCriticalSection> Base;
113 public:
114 
115     /* Please see man pages for details
116 
117 
118 
119 
120 
121 
122 
123     */
InterCoreBlockingQueue()124     InterCoreBlockingQueue() {}
125 
126     /* Please see man pages for details
127 
128 
129 
130 
131 
132 
133     */
InterCoreBlockingQueue(uptr buffer[],size_t size)134     InterCoreBlockingQueue(uptr buffer[], size_t size) : Base(buffer, size) {}
135 
136     /* Please see man pages for details
137 
138 
139 
140     */
~InterCoreBlockingQueue()141     ~InterCoreBlockingQueue() { Finalize(); }
142 
143     /* Please see man pages for details
144 
145 
146 
147 
148 
149 
150     */
Initialize(uptr buffer[],size_t size)151     void Initialize(uptr buffer[], size_t size) { Base::Initialize(buffer, size); }
152 
153     /* Please see man pages for details
154 
155 
156 
157 
158 
159 
160 
161 
162     */
TryInitialize(uptr buffer[],size_t size)163     nn::Result TryInitialize(uptr buffer[], size_t size) { return Base::TryInitialize(buffer, size); }
164 
165     /* Please see man pages for details
166 
167 
168 
169 
170 
171     */
Finalize()172     void Finalize() { Base::Finalize(); }
173 
174     /* Please see man pages for details
175 
176 
177 
178 
179 
180 
181 
182 
183 
184 
185 
186 
187     */
Enqueue(uptr data)188     void Enqueue(uptr data) { Base::Enqueue(data); }
189 
190     /* Please see man pages for details
191 
192 
193 
194 
195 
196 
197 
198 
199 
200 
201 
202     */
TryEnqueue(uptr data)203     bool TryEnqueue(uptr data) { return Base::TryEnqueue(data); }
204 
205     /* Please see man pages for details
206 
207 
208 
209 
210 
211 
212 
213 
214 
215 
216 
217 
218     */
Jam(uptr data)219     void Jam(uptr data) { Base::Jam(data); }
220 
221     /* Please see man pages for details
222 
223 
224 
225 
226 
227 
228 
229 
230 
231 
232 
233     */
TryJam(uptr data)234     bool TryJam(uptr data) { return Base::TryJam(data); }
235 
236     /* Please see man pages for details
237 
238 
239 
240 
241 
242 
243 
244 
245 
246     */
Dequeue()247     uptr Dequeue() { return Base::Dequeue(); }
248 
249     /* Please see man pages for details
250 
251 
252 
253 
254 
255 
256 
257 
258 
259 
260 
261     */
TryDequeue(uptr * pOut)262     bool TryDequeue(uptr* pOut) { return Base::TryDequeue(pOut); }
263 
264     /* Please see man pages for details
265 
266 
267 
268 
269 
270 
271     */
GetFront()272     uptr GetFront() const { return Base::GetFront(); }
273 
274     /* Please see man pages for details
275 
276 
277 
278 
279 
280 
281 
282 
283     */
TryGetFront(uptr * pOut)284     bool TryGetFront(uptr* pOut) const { return Base::TryGetFront(pOut); }
285 
286     // TODO: For testing
287     using Base::GetSize;
288     using Base::GetUsedCount;
289     using Base::GetFirstIndex;
290 
291 };
292 
293 
294 }}
295 
296 #endif
297 
298 // C declarations follow
299 
300 #include <nn/util/detail/util_CLibImpl.h>
301 
302 NN_UTIL_DETAIL_CLIBIMPL_DEFINE_BUFFER_CLASS(nnosInterCoreBlockingQueue, nn::os::InterCoreBlockingQueue, 40 + NN_OS_INTERCORE_CRITICALSECTION_SIZE, u32);
303 
304 NN_EXTERN_C void nnosInterCoreBlockingQueueInitialize(nnosInterCoreBlockingQueue* this_, uptr buffer[], size_t size);
305 
306 NN_EXTERN_C bool nnosInterCoreBlockingQueueTryInitialize(nnosInterCoreBlockingQueue* this_, uptr buffer[], size_t size);
307 
308 NN_EXTERN_C void nnosInterCoreBlockingQueueFinalize(nnosInterCoreBlockingQueue* this_);
309 
310 NN_EXTERN_C bool nnosInterCoreBlockingQueueTryEnqueue(nnosInterCoreBlockingQueue* this_, uptr data);
311 
312 NN_EXTERN_C void nnosInterCoreBlockingQueueEnqueue(nnosInterCoreBlockingQueue* this_, uptr data);
313 
314 NN_EXTERN_C bool nnosInterCoreBlockingQueueTryJam(nnosInterCoreBlockingQueue* this_, uptr data);
315 
316 NN_EXTERN_C void nnosInterCoreBlockingQueueJam(nnosInterCoreBlockingQueue* this_, uptr data);
317 
318 NN_EXTERN_C bool nnosInterCoreBlockingQueueTryDequeue(nnosInterCoreBlockingQueue* this_, uptr* pOut);
319 
320 NN_EXTERN_C uptr nnosInterCoreBlockingQueueDequeue(nnosInterCoreBlockingQueue* this_);
321 
322 NN_EXTERN_C bool nnosInterCoreBlockingQueueTryGetFront(nnosInterCoreBlockingQueue* this_, uptr* pOut);
323 
324 NN_EXTERN_C uptr nnosInterCoreBlockingQueueGetFront(nnosInterCoreBlockingQueue* this_);
325 
326 #endif
327