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: 30205 $ 14 *---------------------------------------------------------------------------*/ 15 16 /*! @file 17 @brief BlockingQueue に関する API の宣言 18 19 :include nn/os.h 20 */ 21 22 #ifndef NN_OS_OS_BLOCKINGQUEUE_H_ 23 #define NN_OS_OS_BLOCKINGQUEUE_H_ 24 25 #include <nn/os/os_LightSemaphore.h> 26 #include <nn/os/os_Mutex.h> 27 #include <nn/os/os_CriticalSection.h> 28 #include <nn/os/os_InterCoreCriticalSection.h> 29 #include <nn/fnd/fnd_Interlocked.h> 30 #include <nn/util/util_NonCopyable.h> 31 32 #ifdef __cplusplus 33 34 namespace nn { namespace os { 35 36 namespace detail { 37 38 /*! 39 :private 40 41 @brief ブロッキングキューの基底クラスです。 42 */ 43 template <class Locker> 44 class BlockingQueueBase : private nn::util::NonCopyable<BlockingQueueBase<Locker> > 45 { 46 protected: BlockingQueueBase()47 BlockingQueueBase() {} BlockingQueueBase(uptr buffer[],size_t size)48 BlockingQueueBase(uptr buffer[], size_t size) { Initialize(buffer, size); } 49 ~BlockingQueueBase(); 50 void Initialize(uptr buffer[], size_t size); 51 nn::Result TryInitialize(uptr buffer[], size_t size); 52 void Finalize(); 53 void Enqueue(uptr data); 54 bool TryEnqueue(uptr data); 55 bool ForceEnqueue(uptr data, uptr* pOut); 56 void Jam(uptr data); 57 bool TryJam(uptr data); 58 uptr Dequeue(); 59 bool TryDequeue(uptr* pOut); 60 uptr GetFront() const; 61 bool TryGetFront(uptr* pOut) const; 62 63 // TODO: これらの関数の扱いを決める 64 GetWaitingEnqueueCount(void)65 s32 GetWaitingEnqueueCount(void) const 66 { return m_WaitingEnqueueCount; } 67 GetWaitingDequeueCount(void)68 s32 GetWaitingDequeueCount(void) const 69 { return m_WaitingDequeueCount; } 70 71 // テスト用内部メンバアクセサ GetSize()72 s32 GetSize() const 73 { return m_size; } 74 GetUsedCount()75 s32 GetUsedCount() const 76 { return m_usedCount; } 77 GetFirstIndex()78 s32 GetFirstIndex() const 79 { return m_firstIndex; } 80 81 private: 82 typedef typename Locker::ScopedLock ScopedLock; 83 84 uptr* m_ppBuffer; //!< キュー用バッファ 85 mutable LightSemaphore m_EnqueueSemaphore; //!< キューへの挿入待ち用同期オブジェクト 86 mutable LightSemaphore m_DequeueSemaphore; //!< キューからの取り出し待ち用同期オブジェクト 87 mutable Locker m_cs; //!< キュー操作用同期オブジェクト 88 size_t m_size; //!< キューのサイズ 89 s32 m_firstIndex; //!< キューの先頭へのインデックス 90 s32 m_usedCount; //!< キューに入っている要素数 91 mutable nn::fnd::InterlockedVariable<s32> m_WaitingEnqueueCount; //!< キューに挿入処理中のスレッド数 92 mutable nn::fnd::InterlockedVariable<s32> m_WaitingDequeueCount; //!< キューから取り出し処理中のスレッド数 93 94 //!< データ挿入待ちスレッドを起床します。 95 void NotifyEnqueue() const; 96 97 //!< キュー空き待ちスレッドを起床します。 98 void NotifyDequeue() const; 99 }; 100 101 } 102 103 /*! 104 @brief ブロッキングキューを扱う為のクラスです。 105 106 ブロッキングキューは安全にスレッド間の同期をとることの出来るメッセージ機構です。 107 108 キューにおくことのできる要素の数は初期化時に与えるバッファのサイズによって制限されます。 109 これを超える数の要素がキューにある際にさらにキューに追加しようとすると、スレッドがブロックします。 110 同様に、キューの要素が空のときにキューから要素を取り出そうとすると、スレッドがブロックします。 111 112 今までメッセージキューと呼ばれていた機能と同等の機能を有しています。 113 114 内部でのスレッド同期に、@ref CriticalSection を用いているため、 115 優先度逆転を起こすような状況では、デッドロックする可能性があります。 116 そのような可能性がある場合には、@ref SafeBlockingQueue を使うようにしてください。 117 118 */ 119 class BlockingQueue : private os::detail::BlockingQueueBase<nn::os::CriticalSection> 120 { 121 private: 122 typedef os::detail::BlockingQueueBase<nn::os::CriticalSection> Base; 123 public: 124 125 /*! 126 @brief コンストラクタです。 127 128 ブロッキングキューを構築します。 129 130 初期化処理を行わないコンストラクタと、初期化処理を行うコンストラクタがあります。 131 132 コンストラクタで初期化しない場合、使用する前には別途 @ref Initialize を呼んで初期化する必要があります。 133 */ BlockingQueue()134 BlockingQueue() {} 135 136 /*! 137 @brief コンストラクタです。 138 139 ブロッキングキューを構築し、初期化します。 140 141 @param[in] buffer キューに使用するバッファ。uptr 型の配列を指定します。 142 @param[in] size バッファのサイズ。配列の要素数を指定します。 143 */ BlockingQueue(uptr buffer[],size_t size)144 BlockingQueue(uptr buffer[], size_t size) : Base(buffer, size) {} 145 146 /*! 147 @brief デストラクタです。 148 149 内部で @ref Finalize を呼びます。 150 */ ~BlockingQueue()151 ~BlockingQueue() { Finalize(); } 152 153 /*! 154 @brief ブロッキングキューを指定したバッファとサイズで初期化します。 155 156 @param[in] buffer キューに使用するバッファ。uptr 型の配列を指定します。 157 @param[in] size バッファのサイズ。配列の要素数を指定します。 158 159 @return 無し。 160 */ Initialize(uptr buffer[],size_t size)161 void Initialize(uptr buffer[], size_t size) { Base::Initialize(buffer, size); } 162 163 /*! 164 @brief ブロッキングキューを指定したバッファとサイズで初期化します。 165 166 初期化に失敗した際は、失敗に応じた Result 値を返します。 167 168 @param[in] buffer キューに使用するバッファ。uptr 型の配列を指定します。 169 @param[in] size バッファのサイズ。配列の要素数を指定します。 170 171 @return 関数の実行結果を返します。 172 */ TryInitialize(uptr buffer[],size_t size)173 nn::Result TryInitialize(uptr buffer[], size_t size) { return Base::TryInitialize(buffer, size); } 174 175 /*! 176 @brief ブロッキングキューを破棄します。 177 178 デストラクタから自動的に呼び出されますが、明示的に呼ぶこともできます。 179 180 @return 無し。 181 */ Finalize()182 void Finalize() { Base::Finalize(); } 183 184 /*! 185 @brief キューの末尾に要素を挿入します。 186 187 キューの末尾にデータを挿入しますが、 188 キューが一杯 (full) であれば、この関数を呼び出したスレッドはブロックされます。 189 受信スレッドが動作して、キューからデータを取り出すとすぐに再開されます。 190 191 @ref Dequeue や @ref GetFront で待っているスレッドがあった場合、 192 これらのスレッドが起こされます。 193 194 @param[in] data 挿入する要素 195 196 @return 無し。 197 */ Enqueue(uptr data)198 void Enqueue(uptr data) { Base::Enqueue(data); } 199 200 /*! 201 @brief キューの末尾への要素の挿入を試行します。 202 203 キューに空きがあれば、末尾に要素を挿入し、true を返します。 204 キューに空きが無いとき、何もせず、false を返します。 205 206 要素の挿入がされたときに @ref Dequeue や @ref GetFront で待っているスレッドがあった場合、 207 これらのスレッドが起こされます。 208 209 @param[in] data 挿入する要素 210 211 @return 挿入されたとき true を返し、挿入されなかったとき false を返します。 212 */ TryEnqueue(uptr data)213 bool TryEnqueue(uptr data) { return Base::TryEnqueue(data); } 214 215 /*! 216 @brief キューの先頭に要素を挿入します。 217 218 キューの先頭にデータを挿入しますが、 219 キューが一杯 (full) であれば、この関数を呼び出したスレッドはブロックされます。 220 受信スレッドが動作して、キューからデータを取り出すとすぐに再開されます。 221 222 @ref Dequeue や @ref GetFront で待っているスレッドがあった場合、 223 これらのスレッドが起こされます。 224 225 @param[in] data 挿入する要素 226 227 @return 無し。 228 */ Jam(uptr data)229 void Jam(uptr data) { Base::Jam(data); } 230 231 /*! 232 @brief キューの先頭への要素の挿入を試行します。 233 234 キューに空きがあれば、先頭に要素を挿入し、true を返します。 235 キューに空きが無いとき、何もせず、false を返します。 236 237 要素の挿入がされたときに @ref Dequeue や @ref GetFront で待っているスレッドがあった場合、 238 これらのスレッドが起こされます。 239 240 @param[in] data 挿入する要素 241 242 @return 挿入されたとき true を返し、挿入されなかったとき false を返します。 243 */ TryJam(uptr data)244 bool TryJam(uptr data) { return Base::TryJam(data); } 245 246 /*! 247 @brief キューの先頭から要素を取り出します。 248 249 キューが空であるとき、キューが空でなくなるまでスレッドをブロックします。 250 キューが空でなければ、キューの先頭から要素を取り出しすぐに処理を返します。 251 252 @ref Enqueue や @ref Jam で待っているスレッドがあった場合、 253 これらのスレッドが起こされます。 254 255 @return キューから取り出した要素 256 */ Dequeue()257 uptr Dequeue() { return Base::Dequeue(); } 258 259 /*! 260 @brief キューの先頭から要素を取り出します。 261 262 キューが空でなれば、キューの先頭から要素を取り出し、true を返します。 263 キューが空のとき、何もせず、false を返します。 264 265 要素の挿入がされたときに @ref Dequeue や @ref GetFront で待っているスレッドがあった場合、 266 これらのスレッドが起こされます。 267 268 @param[out] pOut 取り出した要素を書き込むバッファ 269 270 @return 要素を取り出したとき true を返し、取り出さなかったとき false を返します。 271 */ TryDequeue(uptr * pOut)272 bool TryDequeue(uptr* pOut) { return Base::TryDequeue(pOut); } 273 274 /*! 275 @brief キューの先頭から要素を取得します。 276 277 キューが空であるとき、キューが空でなくなるまでスレッドをブロックします。 278 キューが空でなければ、キューの先頭の要素を取得します。キューの状態は変化しません。 279 280 @return キューの先頭の要素 281 */ GetFront()282 uptr GetFront() const { return Base::GetFront(); } 283 284 /*! 285 @brief キューの先頭から要素を取得します。 286 287 キューが空であるとき、何もせず false を返します。 288 キューが空でなければ、キューの先頭の要素を *pOut に書き込み、true を返します。キューの状態は変化しません。 289 290 @param[out] pOut 取り出す値の格納先 291 292 @return 要素を取得できたとき true を返し、取得できなかったとき false を返します。 293 */ TryGetFront(uptr * pOut)294 bool TryGetFront(uptr* pOut) const { return Base::TryGetFront(pOut); } 295 296 // TODO: テスト用 297 using Base::GetSize; 298 using Base::GetUsedCount; 299 using Base::GetFirstIndex; 300 301 }; 302 303 304 /*! :private 305 @brief ブロッキングキューを扱う為のクラスです。 306 307 基本的に @ref BlockingQueue と同じですが、スレッド同期に @ref InterCoreCriticalSection を 308 使っており、マルチコア間の同期に使用することを目的としています。 309 */ 310 class InterCoreBlockingQueue : private os::detail::BlockingQueueBase<nn::os::InterCoreCriticalSection> 311 { 312 private: 313 typedef os::detail::BlockingQueueBase<nn::os::InterCoreCriticalSection> Base; 314 public: 315 316 /*! :private 317 @brief コンストラクタです。 318 319 ブロッキングキューを構築します。 320 321 初期化処理を行わないコンストラクタと、初期化処理を行うコンストラクタがあります。 322 323 コンストラクタで初期化しない場合、使用する前には別途 @ref Initialize を呼んで初期化する必要があります。 324 */ InterCoreBlockingQueue()325 InterCoreBlockingQueue() {} 326 327 /*! :private 328 @brief コンストラクタです。 329 330 ブロッキングキューを構築し、初期化します。 331 332 @param[in] buffer キューに使用するバッファ。uptr 型の配列を指定します。 333 @param[in] size バッファのサイズ。配列の要素数を指定します。 334 */ InterCoreBlockingQueue(uptr buffer[],size_t size)335 InterCoreBlockingQueue(uptr buffer[], size_t size) : Base(buffer, size) {} 336 337 /*! :private 338 @brief デストラクタです。 339 340 内部で @ref Finalize を呼びます。 341 */ ~InterCoreBlockingQueue()342 ~InterCoreBlockingQueue() { Finalize(); } 343 344 /*! :private 345 @brief ブロッキングキューを指定したバッファとサイズで初期化します。 346 347 @param[in] buffer キューに使用するバッファ。uptr 型の配列を指定します。 348 @param[in] size バッファのサイズ。配列の要素数を指定します。 349 350 @return 無し。 351 */ Initialize(uptr buffer[],size_t size)352 void Initialize(uptr buffer[], size_t size) { Base::Initialize(buffer, size); } 353 354 /*! :private 355 @brief ブロッキングキューを指定したバッファとサイズで初期化します。 356 357 初期化に失敗した際は、失敗に応じた Result 値を返します。 358 359 @param[in] buffer キューに使用するバッファ。uptr 型の配列を指定します。 360 @param[in] size バッファのサイズ。配列の要素数を指定します。 361 362 @return 関数の実行結果を返します。 363 */ TryInitialize(uptr buffer[],size_t size)364 nn::Result TryInitialize(uptr buffer[], size_t size) { return Base::TryInitialize(buffer, size); } 365 366 /*! :private 367 @brief ブロッキングキューを破棄します。 368 369 デストラクタから自動的に呼び出されますが、明示的に呼ぶこともできます。 370 371 @return 無し。 372 */ Finalize()373 void Finalize() { Base::Finalize(); } 374 375 /*! :private 376 @brief キューの末尾に要素を挿入します。 377 378 キューの末尾にデータを挿入しますが、 379 キューが一杯 (full) であれば、この関数を呼び出したスレッドはブロックされます。 380 受信スレッドが動作して、キューからデータを取り出すとすぐに再開されます。 381 382 @ref Dequeue や @ref GetFront で待っているスレッドがあった場合、 383 これらのスレッドが起こされます。 384 385 @param[in] data 挿入する要素 386 387 @return 無し。 388 */ Enqueue(uptr data)389 void Enqueue(uptr data) { Base::Enqueue(data); } 390 391 /*! :private 392 @brief キューの末尾への要素の挿入を試行します。 393 394 キューに空きがあれば、末尾に要素を挿入し、true を返します。 395 キューに空きが無いとき、何もせず、false を返します。 396 397 要素の挿入がされたときに @ref Dequeue や @ref GetFront で待っているスレッドがあった場合、 398 これらのスレッドが起こされます。 399 400 @param[in] data 挿入する要素 401 402 @return 挿入されたとき true を返し、挿入されなかったとき false を返します。 403 */ TryEnqueue(uptr data)404 bool TryEnqueue(uptr data) { return Base::TryEnqueue(data); } 405 406 /*! :private 407 @brief キューの先頭に要素を挿入します。 408 409 キューの先頭にデータを挿入しますが、 410 キューが一杯 (full) であれば、この関数を呼び出したスレッドはブロックされます。 411 受信スレッドが動作して、キューからデータを取り出すとすぐに再開されます。 412 413 @ref Dequeue や @ref GetFront で待っているスレッドがあった場合、 414 これらのスレッドが起こされます。 415 416 @param[in] data 挿入する要素 417 418 @return 無し。 419 */ Jam(uptr data)420 void Jam(uptr data) { Base::Jam(data); } 421 422 /*! :private 423 @brief キューの先頭への要素の挿入を試行します。 424 425 キューに空きがあれば、先頭に要素を挿入し、true を返します。 426 キューに空きが無いとき、何もせず、false を返します。 427 428 要素の挿入がされたときに @ref Dequeue や @ref GetFront で待っているスレッドがあった場合、 429 これらのスレッドが起こされます。 430 431 @param[in] data 挿入する要素 432 433 @return 挿入されたとき true を返し、挿入されなかったとき false を返します。 434 */ TryJam(uptr data)435 bool TryJam(uptr data) { return Base::TryJam(data); } 436 437 /*! :private 438 @brief キューの先頭から要素を取り出します。 439 440 キューが空であるとき、キューが空でなくなるまでスレッドをブロックします。 441 キューが空でなければ、キューの先頭から要素を取り出しすぐに処理を返します。 442 443 @ref Enqueue や @ref Jam で待っているスレッドがあった場合、 444 これらのスレッドが起こされます。 445 446 @return キューから取り出した要素 447 */ Dequeue()448 uptr Dequeue() { return Base::Dequeue(); } 449 450 /*! :private 451 @brief キューの先頭から要素を取り出します。 452 453 キューが空でなれば、キューの先頭から要素を取り出し、true を返します。 454 キューが空のとき、何もせず、false を返します。 455 456 要素の挿入がされたときに @ref Dequeue や @ref GetFront で待っているスレッドがあった場合、 457 これらのスレッドが起こされます。 458 459 @param[out] pOut 取り出した要素を書き込むバッファ 460 461 @return 要素を取り出したとき true を返し、取り出さなかったとき false を返します。 462 */ TryDequeue(uptr * pOut)463 bool TryDequeue(uptr* pOut) { return Base::TryDequeue(pOut); } 464 465 /*! :private 466 @brief キューの先頭から要素を取得します。 467 468 キューが空であるとき、キューが空でなくなるまでスレッドをブロックします。 469 キューが空でなければ、キューの先頭の要素を取得します。キューの状態は変化しません。 470 471 @return キューの先頭の要素 472 */ GetFront()473 uptr GetFront() const { return Base::GetFront(); } 474 475 /*! :private 476 @brief キューの先頭から要素を取得します。 477 478 キューが空であるとき、何もせず false を返します。 479 キューが空でなければ、キューの先頭の要素を *pOut に書き込み、true を返します。キューの状態は変化しません。 480 481 @param[out] pOut 取り出す値の格納先 482 483 @return 要素を取得できたとき true を返し、取得できなかったとき false を返します。 484 */ TryGetFront(uptr * pOut)485 bool TryGetFront(uptr* pOut) const { return Base::TryGetFront(pOut); } 486 487 // TODO: テスト用 488 using Base::GetSize; 489 using Base::GetUsedCount; 490 using Base::GetFirstIndex; 491 492 }; 493 494 495 496 /*! 497 @brief ブロッキングキューを扱う為のクラスです。 498 499 基本的に @ref BlockingQueue と同じですが、スレッド同期に @ref Mutex を使っているため、優先度逆転を起こすことがありません。 500 その代わり、若干パフォーマンスは落ちる可能性があります。 501 */ 502 class SafeBlockingQueue : private os::detail::BlockingQueueBase<nn::os::Mutex> 503 { 504 private: 505 typedef os::detail::BlockingQueueBase<nn::os::Mutex> Base; 506 public: 507 508 /*! 509 @brief コンストラクタです。 510 511 ブロッキングキューを構築します。初期化はしません。使用する前には別途 @ref Initialize を呼んで初期化する必要があります。 512 */ SafeBlockingQueue()513 SafeBlockingQueue() {} 514 515 /*! 516 @brief コンストラクタです。 517 518 ブロッキングキューを構築し、初期化します。 519 520 @param[in] buffer キューに使用するバッファ。uptr 型の配列を指定します。 521 @param[in] size バッファのサイズ。配列の要素数を指定します。 522 */ SafeBlockingQueue(uptr buffer[],size_t size)523 SafeBlockingQueue(uptr buffer[], size_t size) : Base(buffer, size) {} 524 525 /*! 526 @brief デストラクタです。 527 528 内部で @ref Finalize を呼びます。 529 */ ~SafeBlockingQueue()530 ~SafeBlockingQueue() {} 531 532 /*! 533 @brief ブロッキングキューを指定したバッファとサイズで初期化します。 534 535 @param[in] buffer キューに使用するバッファ。uptr 型の配列を指定します。 536 @param[in] size バッファのサイズ。配列の要素数を指定します。 537 538 @return 無し。 539 */ Initialize(uptr buffer[],size_t size)540 void Initialize(uptr buffer[], size_t size) { Base::Initialize(buffer, size); } 541 542 /*! 543 @brief ブロッキングキューを指定したバッファとサイズで初期化します。 544 545 初期化に失敗した際は、失敗に応じた Result 値を返します。 546 547 @param[in] buffer キューに使用するバッファ。uptr 型の配列を指定します。 548 @param[in] size バッファのサイズ。配列の要素数を指定します。 549 550 @return 関数の実行結果を返します。 551 */ TryInitialize(uptr buffer[],size_t size)552 nn::Result TryInitialize(uptr buffer[], size_t size) { return Base::TryInitialize(buffer, size); } 553 554 /*! 555 @brief ブロッキングキューを破棄します。 556 557 デストラクタから自動的に呼び出されますが、明示的に呼ぶこともできます。 558 559 @return 無し。 560 */ Finalize()561 void Finalize() { Base::Finalize(); } 562 563 /*! 564 @brief キューの末尾に要素を挿入します。 565 566 キューの末尾にデータを挿入しますが、 567 キューが一杯 (full) であれば、この関数を呼び出したスレッドはブロックされます。 568 受信スレッドが動作して、キューからデータを取り出すとすぐに再開されます。 569 570 @ref Dequeue や @ref GetFront で待っているスレッドがあった場合、 571 これらのスレッドが起こされます。 572 573 @param[in] data 挿入する要素 574 575 @return 無し。 576 */ Enqueue(uptr data)577 void Enqueue(uptr data) { Base::Enqueue(data); } 578 579 /*! 580 @brief キューの末尾への要素の挿入を試行します。 581 582 キューに空きがあれば、末尾に要素を挿入し、true を返します。 583 キューに空きが無いとき、何もせず、false を返します。 584 585 要素の挿入がされたときに @ref Dequeue や @ref GetFront で待っているスレッドがあった場合、 586 これらのスレッドが起こされます。 587 588 @param[in] data 挿入する要素 589 590 @return 挿入されたとき true を返し、挿入されなかったとき false を返します。 591 */ TryEnqueue(uptr data)592 bool TryEnqueue(uptr data) { return Base::TryEnqueue(data); } 593 594 /*! 595 @brief キューの先頭に要素を挿入します。 596 597 キューの先頭にデータを挿入しますが、 598 キューが一杯 (full) であれば、この関数を呼び出したスレッドはブロックされます。 599 受信スレッドが動作して、キューからデータを取り出すとすぐに再開されます。 600 601 @ref Dequeue や @ref GetFront で待っているスレッドがあった場合、 602 これらのスレッドが起こされます。 603 604 @param[in] data 挿入する要素 605 606 @return 無し。 607 */ Jam(uptr data)608 void Jam(uptr data) { Base::Jam(data); } 609 610 /*! 611 @brief キューの先頭への要素の挿入を試行します。 612 613 キューに空きがあれば、先頭に要素を挿入し、true を返します。 614 キューに空きが無いとき、何もせず、false を返します。 615 616 要素の挿入がされたときに @ref Dequeue や @ref GetFront で待っているスレッドがあった場合、 617 これらのスレッドが起こされます。 618 619 @param[in] data 挿入する要素 620 621 @return 挿入されたとき true を返し、挿入されなかったとき false を返します。 622 */ TryJam(uptr data)623 bool TryJam(uptr data) { return Base::TryJam(data); } 624 625 /*! 626 @brief キューの先頭から要素を取り出します。 627 628 キューが空であるとき、キューが空でなくなるまでスレッドをブロックします。 629 キューが空でなければ、キューの先頭から要素を取り出しすぐに処理を返します。 630 631 @ref Enqueue や @ref Jam で待っているスレッドがあった場合、 632 これらのスレッドが起こされます。 633 634 @return キューから取り出した要素 635 */ Dequeue()636 uptr Dequeue() { return Base::Dequeue(); } 637 638 /*! 639 @brief キューの先頭から要素を取り出します。 640 641 キューが空でなれば、キューの先頭から要素を取り出し、true を返します。 642 キューが空のとき、何もせず、false を返します。 643 644 要素の挿入がされたときに @ref Dequeue や @ref GetFront で待っているスレッドがあった場合、 645 これらのスレッドが起こされます。 646 647 @param[out] pOut 取り出した要素を書き込むバッファ 648 649 @return 要素を取り出したとき true を返し、取り出さなかったとき false を返します。 650 */ TryDequeue(uptr * pOut)651 bool TryDequeue(uptr* pOut) { return Base::TryDequeue(pOut); } 652 653 /*! 654 @brief キューの先頭から要素を取得します。 655 656 キューが空であるとき、キューが空でなくなるまでスレッドをブロックします。 657 キューが空でなければ、キューの先頭の要素を取得します。キューの状態は変化しません。 658 659 @return キューの先頭の要素 660 */ GetFront()661 uptr GetFront() const { return Base::GetFront(); } 662 663 /*! 664 @brief キューの先頭から要素を取得します。 665 666 キューが空であるとき、何もせず false を返します。 667 キューが空でなければ、キューの先頭の要素を *pOut に書き込み、true を返します。キューの状態は変化しません。 668 669 @param[out] pOut 取り出す値の格納先 670 671 @return 要素を取得できたとき true を返し、取得できなかったとき false を返します。 672 */ TryGetFront(uptr * pOut)673 bool TryGetFront(uptr* pOut) const { return Base::TryGetFront(pOut); } 674 675 // TODO: テスト用 676 using Base::GetSize; 677 using Base::GetUsedCount; 678 using Base::GetFirstIndex; 679 680 }; 681 682 }} 683 684 #endif 685 686 // 以下、C 用宣言 687 688 #include <nn/util/detail/util_CLibImpl.h> 689 690 /*! 691 @addtogroup nn_os os 692 @{ 693 694 @defgroup nn_os_BlockingQueue_c BlockingQueue (C) 695 696 @brief @ref nn::os::BlockingQueue の C インタフェースモジュールです。 697 698 @{ 699 */ 700 701 702 /*! 703 @struct nnosBlockingQueue 704 @brief ブロッキングキューを表す C の構造体です。 705 706 @brief 対応するクラス @ref nn::os::BlockingQueue を参照してください。 707 */ 708 NN_UTIL_DETAIL_CLIBIMPL_DEFINE_BUFFER_CLASS(nnosBlockingQueue, nn::os::BlockingQueue, 40 + NN_OS_CRITICALSECTION_SIZE, u32); 709 710 /*! 711 @brief 対応する C++ 関数を参照してください。@ref nn::os::BlockingQueue::Initialize 712 */ 713 NN_EXTERN_C void nnosBlockingQueueInitialize(nnosBlockingQueue* this_, uptr buffer[], size_t size); 714 715 /*! 716 @brief 対応する C++ 関数を参照してください。@ref nn::os::BlockingQueue::TryInitialize 717 */ 718 NN_EXTERN_C bool nnosBlockingQueueTryInitialize(nnosBlockingQueue* this_, uptr buffer[], size_t size); 719 720 /*! 721 @brief 対応する C++ 関数を参照してください。@ref nn::os::BlockingQueue::Finalize 722 */ 723 NN_EXTERN_C void nnosBlockingQueueFinalize(nnosBlockingQueue* this_); 724 725 /*! 726 @brief 対応する C++ 関数を参照してください。@ref nn::os::BlockingQueue::TryEnqueue 727 */ 728 NN_EXTERN_C bool nnosBlockingQueueTryEnqueue(nnosBlockingQueue* this_, uptr data); 729 730 /*! 731 @brief 対応する C++ 関数を参照してください。@ref nn::os::BlockingQueue::Enqueue 732 */ 733 NN_EXTERN_C void nnosBlockingQueueEnqueue(nnosBlockingQueue* this_, uptr data); 734 735 /*! 736 @brief 対応する C++ 関数を参照してください。@ref nn::os::BlockingQueue::TryJam 737 */ 738 NN_EXTERN_C bool nnosBlockingQueueTryJam(nnosBlockingQueue* this_, uptr data); 739 740 /*! 741 @brief 対応する C++ 関数を参照してください。@ref nn::os::BlockingQueue::Jam 742 */ 743 NN_EXTERN_C void nnosBlockingQueueJam(nnosBlockingQueue* this_, uptr data); 744 745 /*! 746 @brief 対応する C++ 関数を参照してください。@ref nn::os::BlockingQueue::TryDequeue 747 */ 748 NN_EXTERN_C bool nnosBlockingQueueTryDequeue(nnosBlockingQueue* this_, uptr* pOut); 749 750 /*! 751 @brief 対応する C++ 関数を参照してください。@ref nn::os::BlockingQueue::Dequeue 752 */ 753 NN_EXTERN_C uptr nnosBlockingQueueDequeue(nnosBlockingQueue* this_); 754 755 /*! 756 @brief 対応する C++ 関数を参照してください。@ref nn::os::BlockingQueue::TryGetFront 757 */ 758 NN_EXTERN_C bool nnosBlockingQueueTryGetFront(nnosBlockingQueue* this_, uptr* pOut); 759 760 /*! 761 @brief 対応する C++ 関数を参照してください。@ref nn::os::BlockingQueue::GetFront 762 */ 763 NN_EXTERN_C uptr nnosBlockingQueueGetFront(nnosBlockingQueue* this_); 764 765 /*! 766 @} 767 768 @} 769 */ 770 771 772 /*! 773 @addtogroup nn_os os 774 @{ 775 776 @defgroup nn_os_SafeBlockingQueue_c SafeBlockingQueue (C) 777 778 @brief @ref nn::os::SafeBlockingQueue の C インタフェースモジュールです。 779 780 @{ 781 */ 782 783 /*! 784 @struct nnosSafeBlockingQueue 785 @brief セーフブロッキングキューを表す C の構造体です。 786 787 @brief 対応するクラス @ref nn::os::SafeBlockingQueue を参照してください。 788 */ 789 NN_UTIL_DETAIL_CLIBIMPL_DEFINE_BUFFER_CLASS(nnosSafeBlockingQueue, nn::os::SafeBlockingQueue, 44, u32); 790 791 /*! 792 @brief 対応する C++ 関数を参照してください。@ref nn::os::SafeBlockingQueue::Initialize 793 */ 794 NN_EXTERN_C void nnosSafeBlockingQueueInitialize(nnosSafeBlockingQueue* this_, uptr buffer[], size_t size); 795 796 /*! 797 @brief 対応する C++ 関数を参照してください。@ref nn::os::SafeBlockingQueue::TryInitialize 798 */ 799 NN_EXTERN_C bool nnosSafeBlockingQueueTryInitialize(nnosSafeBlockingQueue* this_, uptr buffer[], size_t size); 800 801 /*! 802 @brief 対応する C++ 関数を参照してください。@ref nn::os::SafeBlockingQueue::Finalize 803 */ 804 NN_EXTERN_C void nnosSafeBlockingQueueFinalize(nnosSafeBlockingQueue* this_); 805 806 /*! 807 @brief 対応する C++ 関数を参照してください。@ref nn::os::SafeBlockingQueue::TryEnqueue 808 */ 809 NN_EXTERN_C bool nnosSafeBlockingQueueTryEnqueue(nnosSafeBlockingQueue* this_, uptr data); 810 811 /*! 812 @brief 対応する C++ 関数を参照してください。@ref nn::os::SafeBlockingQueue::Enqueue 813 814 */ 815 NN_EXTERN_C void nnosSafeBlockingQueueEnqueue(nnosSafeBlockingQueue* this_, uptr data); 816 817 /*! 818 @brief 対応する C++ 関数を参照してください。@ref nn::os::SafeBlockingQueue::TryJam 819 820 */ 821 NN_EXTERN_C bool nnosSafeBlockingQueueTryJam(nnosSafeBlockingQueue* this_, uptr data); 822 823 /*! 824 @brief 対応する C++ 関数を参照してください。@ref nn::os::SafeBlockingQueue::Jam 825 826 */ 827 NN_EXTERN_C void nnosSafeBlockingQueueJam(nnosSafeBlockingQueue* this_, uptr data); 828 829 /*! 830 @brief 対応する C++ 関数を参照してください。@ref nn::os::SafeBlockingQueue::TryDequeue 831 832 */ 833 NN_EXTERN_C bool nnosSafeBlockingQueueTryDequeue(nnosSafeBlockingQueue* this_, uptr* pOut); 834 835 /*! 836 @brief 対応する C++ 関数を参照してください。@ref nn::os::SafeBlockingQueue::Dequeue 837 838 */ 839 NN_EXTERN_C uptr nnosSafeBlockingQueueDequeue(nnosSafeBlockingQueue* this_); 840 841 /*! 842 @brief 対応する C++ 関数を参照してください。@ref nn::os::SafeBlockingQueue::TryGetFront 843 844 */ 845 NN_EXTERN_C bool nnosSafeBlockingQueueTryGetFront(nnosSafeBlockingQueue* this_, uptr* pOut); 846 847 /*! 848 @brief 対応する C++ 関数を参照してください。@ref nn::os::SafeBlockingQueue::GetFront 849 850 */ 851 NN_EXTERN_C uptr nnosSafeBlockingQueueGetFront(nnosSafeBlockingQueue* this_); 852 853 854 /*! 855 @} 856 857 @} 858 */ 859 860 #endif 861