1 /*---------------------------------------------------------------------------* 2 Project: Horizon 3 File: os_LightEvent.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: 12449 $ 14 *---------------------------------------------------------------------------*/ 15 16 #ifndef NN_OS_OS_LIGHTEVENT_H_ 17 #define NN_OS_OS_LIGHTEVENT_H_ 18 19 #ifdef __cplusplus 20 21 #include <nn/os/os_WaitableCounter.h> 22 #include <nn/assert.h> 23 #include <nn/WithInitialize.h> 24 #include <nn/util/detail/util_ScopedLockImpl.h> 25 26 namespace nn { namespace os { 27 28 /*! 29 @file 30 @brief LightEvent に関するAPI の宣言 31 32 :include nn/os.h 33 */ 34 35 /*!--------------------------------------------------------------------------* 36 @brief スレッド間でフラグの通知を行う同期機構です。 37 38 内部にフラグを持ち、このフラグをスレッド間で安全に操作したり、 39 また、フラグがセットされるのを待ち合わせたりすることができます。 40 41 複数の同期オブジェクトを同時に待つことができないという点を除いて 42 nn::os::LightEvent の方が nn::os::Event より 43 優れているため、通常は nn::os::LightEvent を使用すべきです。 44 45 このクラスの初期化/終了以外のメンバ関数はスレッドセーフです。 46 47 *---------------------------------------------------------------------------*/ 48 class LightEvent 49 { 50 private: 51 static const s32 SIGNALED_MANUAL = 1; 52 static const s32 SIGNALED_AUTO = 0; 53 static const s32 NOT_SIGNALED_AUTO = -1; 54 static const s32 NOT_SIGNALED_MANUAL = -2; 55 56 private: 57 WaitableCounter m_Counter; 58 59 public: 60 //---------------------------------------- 61 //! @name 初期化/終了 62 //@{ 63 64 /*!--------------------------------------------------------------------------* 65 @brief コンストラクタです。 66 67 初期化を行わないコンストラクタです。 68 69 別途 @ref Initialize を呼び出す必要があります。 70 71 @return なし。 72 73 *---------------------------------------------------------------------------*/ LightEvent()74 LightEvent(){} 75 76 /*!--------------------------------------------------------------------------* 77 @brief コンストラクタです。 78 79 初期化を行うコンストラクタです。 80 81 別途 @ref Initialize を呼び出す必要はありません。 82 83 自動リセットでは、いずれかのスレッドが 84 フラグがセットされることによって起床した場合、 85 フラグがクリアされます。 86 このため、複数のスレッドが待機していても一回のフラグのセットでは 87 一つのスレッドだけが起床します。 88 89 手動リセットではフラグが自動的にクリアされることはありません。 90 そのため、複数のスレッドが待機しているなら一回のフラグのセットで 91 全てのスレッドが起床します。 92 93 @param[in] isManualReset 手動リセットなら true、 94 自動リセットなら false を指定します。 95 96 @return なし。 97 98 *---------------------------------------------------------------------------*/ LightEvent(bool isManualReset)99 LightEvent(bool isManualReset) 100 { 101 Initialize(isManualReset); 102 } 103 104 /*!--------------------------------------------------------------------------* 105 @brief 初期化を行います。 106 107 @param[in] isManualReset 手動リセットなら true、 108 自動リセットなら false を指定します。 109 110 @return なし。 111 112 *---------------------------------------------------------------------------*/ Initialize(bool isManualReset)113 void Initialize(bool isManualReset) 114 { 115 *m_Counter = isManualReset ? NOT_SIGNALED_MANUAL: NOT_SIGNALED_AUTO; 116 } 117 118 /*!--------------------------------------------------------------------------* 119 @brief 終了処理を行います。 120 121 @return なし。 122 123 *---------------------------------------------------------------------------*/ Finalize()124 void Finalize() {} 125 126 //@} 127 128 //---------------------------------------- 129 //! @name デバッグ用情報取得 130 //@{ 131 132 /*!--------------------------------------------------------------------------* 133 @brief フラグがセットされているかどうかを取得します。 134 135 この関数は主にデバッグ用です。 136 通常は @ref TryWait を用いてください。 137 138 この関数は自動リセットか手動リセットかによらず 139 単純にフラグがセットされているかどうかを取得します。 140 フラグの状態を変更することはしません。 141 142 @return フラグがセットされているなら true、 143 そうでなければ false を返します。 144 145 *---------------------------------------------------------------------------*/ IsSignaled()146 bool IsSignaled() const { return *m_Counter >= 0; } 147 148 /*!--------------------------------------------------------------------------* 149 @brief 手動リセットかどうかを取得します。 150 151 @return 手動リセットなら true、 152 そうでなければ false を返します。 153 154 *---------------------------------------------------------------------------*/ IsManualReset()155 bool IsManualReset() const 156 { 157 const s32 c = *m_Counter; 158 return (c == SIGNALED_MANUAL) || (c == NOT_SIGNALED_MANUAL); 159 } 160 161 //@} 162 163 //---------------------------------------- 164 //! @name フラグの操作と待ち合わせ 165 //@{ 166 167 /*!--------------------------------------------------------------------------* 168 @brief フラグがセットされているかどうかを取得します。 169 170 自動リセットの場合、フラグがセットされているなら 171 フラグのクリアも行います。 172 173 @return フラグがセットされていたなら true、 174 そうでなければ false を返します。 175 176 *---------------------------------------------------------------------------*/ 177 bool TryWait(); 178 179 /*!--------------------------------------------------------------------------* 180 @brief フラグがセットされるまで待機します。 181 182 自動リセットの場合は、フラグがセットされ待機が解除されると 183 同時にフラグをクリアします。 184 185 @return なし。 186 187 *---------------------------------------------------------------------------*/ 188 void Wait(); 189 190 /*!--------------------------------------------------------------------------* 191 @brief フラグをセットします。 192 193 フラグがセットされるのを待機しているスレッドが存在するなら 194 そのスレッドを起床させます。 195 196 自動リセットの場合、複数のスレッドが待機していても 197 起床するスレッドは 1 つだけです。 198 起床するスレッドはスレッド優先度が高い方から優先的に起床します。 199 また、待機しているスレッドが存在するなら、 200 そのスレッドが起床すると同時にフラグがクリアされます。 201 待機しているスレッドが存在しなければ 202 フラグはセットされたままになります。 203 204 手動リセットの場合、全ての待機しているスレッドが起床します。 205 またフラグはセットされたままになります。 206 207 @return なし。 208 209 *---------------------------------------------------------------------------*/ 210 void Signal(); 211 212 /*!--------------------------------------------------------------------------* 213 @brief フラグがセットされるのを待機しているスレッドを解放します。 214 215 自動リセットの場合は待機しているスレッドのうち 216 最もスレッド優先度が高いスレッドを一つだけ起床させ、 217 その後フラグをクリアします。 218 待機しているスレッドが存在しなくてもフラグをクリアする点が 219 Signal と異なります。 220 221 手動リセットの場合は待機している全てのスレッドを起床させ、 222 その後フラグをクリアします。 223 224 @return なし。 225 226 *---------------------------------------------------------------------------*/ 227 void Pulse(); 228 229 /*!--------------------------------------------------------------------------* 230 @brief フラグをクリアします。 231 232 @return なし。 233 234 *---------------------------------------------------------------------------*/ 235 void ClearSignal(); 236 237 //@} 238 }; 239 240 241 }} // namespace nn::os 242 243 #endif // __cplusplus 244 245 // 以下、C 用宣言 246 247 #include <nn/util/detail/util_CLibImpl.h> 248 249 /*! 250 @addtogroup nn_os 251 @{ 252 253 @defgroup nn_os_LightEvent_c LightEvent (C) 254 255 @brief @ref nn::os::LightEvent の C インタフェースモジュールです。 256 257 @{ 258 */ 259 260 /*! 261 @struct nnosLightEvent 262 @brief ライトイベントを表す C の構造体です。 263 @brief 対応するクラス @ref nn::os::LightEvent を参照してください。 264 */ 265 NN_UTIL_DETAIL_CLIBIMPL_DEFINE_BUFFER_CLASS(nnosLightEvent, nn::os::LightEvent, 4, u32); 266 267 /*! 268 @brief 対応する C++ 関数 @ref nn::os::LightEvent::Initialize を参照してください。 269 */ 270 NN_EXTERN_C void nnosLightEventInitialize(nnosLightEvent* this_, bool isManualReset); 271 272 /*! 273 @brief 対応する C++ 関数 @ref nn::os::LightEvent::IsSignaled を参照してください。 274 */ 275 NN_EXTERN_C bool nnosLightEventIsSignaled(nnosLightEvent* this_); 276 277 /*! 278 @brief 対応する C++ 関数 @ref nn::os::LightEvent::IsManualReset を参照してください。 279 */ 280 NN_EXTERN_C bool nnosLightEventIsManualReset(nnosLightEvent* this_); 281 282 /*! 283 @brief 対応する C++ 関数 @ref nn::os::LightEvent::TryWait を参照してください。 284 */ 285 NN_EXTERN_C bool nnosLightEventTryWait(nnosLightEvent* this_); 286 287 /*! 288 @brief 対応する C++ 関数 @ref nn::os::LightEvent::Wait を参照してください。 289 */ 290 NN_EXTERN_C void nnosLightEventWait(nnosLightEvent* this_); 291 292 /*! 293 @brief 対応する C++ 関数 @ref nn::os::LightEvent::Signal を参照してください。 294 */ 295 NN_EXTERN_C void nnosLightEventSignal(nnosLightEvent* this_); 296 297 /*! 298 @brief 対応する C++ 関数 @ref nn::os::LightEvent::Pulse を参照してください。 299 */ 300 NN_EXTERN_C void nnosLightEventPulse(nnosLightEvent* this_); 301 302 /*! 303 @brief 対応する C++ 関数 @ref nn::os::LightEvent::ClearSignal を参照してください。 304 */ 305 NN_EXTERN_C void nnosLightEventClearSignal(nnosLightEvent* this_); 306 307 /*! 308 @brief 対応する C++ 関数 @ref nn::os::LightEvent::Finalize を参照してください。 309 */ 310 NN_EXTERN_C void nnosLightEventFinalize(nnosLightEvent* this_); 311 312 /*! 313 @} 314 315 @} 316 */ 317 318 319 320 #endif // ifndef NN_OS_OS_LIGHTEVENT_H_ 321