1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: os_Synchronization.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: 16692 $
14 *---------------------------------------------------------------------------*/
15
16 /*! @file
17 @brief Synchronization に関する API の宣言
18
19 :include nn/os.h
20 */
21
22 #ifndef NN_OS_OS_SYNCHRONIZATION_H_
23 #define NN_OS_OS_SYNCHRONIZATION_H_
24
25 #include <nn/types.h>
26 #include <nn/Result.h>
27 #include <nn/os/os_HandleObject.h>
28 #include <nn/fnd/fnd_TimeSpan.h>
29
30 #include <nn/util/util_Result.h>
31
32 /*!
33 @def NN_OS_WAIT_INFINITE
34 @brief タイムアウトしないことを表します。
35 */
36 #define NN_OS_WAIT_INFINITE -1
37
38 #ifdef __cplusplus
39
40 namespace nn{ namespace os{
41
42 const s64 WAIT_INFINITE = NN_OS_WAIT_INFINITE;
43
44 /*!
45 @brief Wait することができるオブジェクトの基底クラスです。
46
47 @ref WaitOne でインスタンスオブジェクトを Wait することができます。
48 @ref WaitAny や @ref WaitAll で、複数の WaitObject を同時に Wait することができます。
49 これらの Wait 動作は、オブジェクトの状態変化によって解放されますが、
50 Wait 動作の解放が何を表すかは継承したクラスによります。
51 継承先クラスでは、Wait 動作の具体的な名前を示す名前で、独自の関数が定義されていることがあります。
52
53 Wait 動作をしたスレッドは、Wait 動作が解放されるまでブロックされ、
54 CPU リソースを他のスレッドに明け渡します。
55
56 このクラスを直接インスタンス化することはできません。
57 継承先のクラスを使用してください。
58 */
59 class WaitObject : public HandleObject
60 {
61 public:
62
63 /*!
64 @brief インスタンスオブジェクト一つを待ちます。
65
66 @return 無し。
67 */
68 void WaitOne();
69
70 /*!
71 @brief インスタンスオブジェクト一つをタイムアウトつきで待ちます。
72
73 @param[in] timeout タイムアウト時間を指定します。
74
75 @return falseが返ってきたら、タイムアウトしたことを表します。
76 */
77 bool WaitOne(nn::fnd::TimeSpan timeout);
78
79 /*!
80 @brief 全てのオブジェクトを待ちます。
81
82 @param[in] objs WaitObjectの配列を指定します。
83 @param[in] numObjects WaitObjectの数を指定します。
84
85 @return 無し。
86 */
87 static void WaitAll(WaitObject* objs[], s32 numObjects);
88
89 /*!
90 @brief 全てのオブジェクトをタイムアウトつきで待ちます。
91
92 @param[in] objs WaitObjectの配列を指定します。
93 @param[in] numObjects WaitObjectの数を指定します。
94
95 @param[in] timeout タイムアウト時間を指定します。
96
97 @return false が返ってきたら、タイムアウトしたことを表します。
98 */
99 static bool WaitAll(WaitObject* objs[], s32 numObjects, nn::fnd::TimeSpan timeout);
100
101 //
102 /*!
103 @brief どれか一つのオブジェクトを待ちます。
104
105 @param[in] objs WaitObjectの配列を指定します。
106 @param[in] numObjects WaitObjectの数を指定します。
107
108 @return Wait 動作が解放されたオブジェクトの objs 配列中でのインデックスを返します。
109 */
110 static s32 WaitAny(WaitObject* objs[], s32 numObjects);
111
112 /*!
113 @brief どれか一つのオブジェクトをタイムアウトつきで待ちます。
114
115 @param[in] objs WaitObjectの配列を指定します。
116 @param[in] numObjects WaitObjectの数を指定します。
117
118 @param[in] timeout タイムアウト時間を指定します。
119
120 @return Wait 動作が解放されたオブジェクトの objs 配列中でのインデックスを返します。タイムアウトしたときには負の値が返ります。
121 */
122 static s32 WaitAny(WaitObject* objs[], s32 numObjects, nn::fnd::TimeSpan timeout);
123
124 protected:
125
126 // 単独インスタンス化の禁止
WaitObject()127 WaitObject() {}
~WaitObject()128 ~WaitObject() {}
129
130 private:
131
132 nn::Result WaitOneImpl(s64 nanoSecondsTimeout);
133 static nn::Result WaitMultiple(s32* pOut, WaitObject* objs[], s32 numObjects, bool waitAll, s64 nanoSecondsTimeout);
134
135 };
136
137 /*!
138 @brief ライブラリが内部で使うための抽象クラスです。
139 直接使わないようにしてください。
140
141 */
142 class InterruptEvent : public WaitObject
143 {
144 protected:
InterruptEvent()145 InterruptEvent() {}
~InterruptEvent()146 ~InterruptEvent() {}
147 };
148
149 // インライン実装
150
WaitOneImpl(s64 nanoSecondsTimeout)151 inline nn::Result WaitObject::WaitOneImpl(s64 nanoSecondsTimeout)
152 {
153 s32 dummy;
154 Handle handle = GetHandle();
155 return nn::svc::WaitSynchronization(&dummy, &handle, 1, false, nanoSecondsTimeout);
156 }
157
WaitOne()158 inline void WaitObject::WaitOne()
159 {
160 NN_UTIL_PANIC_IF_FAILED(WaitOneImpl(WAIT_INFINITE));
161 }
162
WaitOne(nn::fnd::TimeSpan timeout)163 inline bool WaitObject::WaitOne(nn::fnd::TimeSpan timeout)
164 {
165 nn::Result result = WaitOneImpl(timeout.GetNanoSeconds());
166 NN_UTIL_PANIC_IF_FAILED(result);
167 return result.GetDescription() != nn::Result::DESCRIPTION_TIMEOUT;
168 }
169
WaitAll(WaitObject * objs[],s32 numObjects,nn::fnd::TimeSpan timeout)170 inline bool WaitObject::WaitAll(WaitObject* objs[], s32 numObjects, nn::fnd::TimeSpan timeout)
171 {
172 s32 dummy;
173 nn::Result result = WaitMultiple(&dummy, objs, numObjects, true, timeout.GetNanoSeconds());
174 NN_UTIL_PANIC_IF_FAILED(result);
175 return result.GetDescription() != nn::Result::DESCRIPTION_TIMEOUT;
176 }
177
WaitAll(WaitObject * objs[],s32 numObjects)178 inline void WaitObject::WaitAll(WaitObject* objs[], s32 numObjects)
179 {
180 s32 dummy;
181 NN_UTIL_PANIC_IF_FAILED(WaitMultiple(&dummy, objs, numObjects, true, WAIT_INFINITE));
182 }
183
WaitAny(WaitObject * objs[],s32 numObjects,nn::fnd::TimeSpan timeout)184 inline s32 WaitObject::WaitAny(WaitObject* objs[], s32 numObjects, nn::fnd::TimeSpan timeout)
185 {
186 s32 ret;
187 nn::Result result = WaitMultiple(&ret, objs, numObjects, false, timeout.GetNanoSeconds());
188 NN_UTIL_PANIC_IF_FAILED(result);
189 return (result.GetDescription() == nn::Result::DESCRIPTION_TIMEOUT) ? -1 : ret;
190 }
191
WaitAny(WaitObject * objs[],s32 numObjects)192 inline s32 WaitObject::WaitAny(WaitObject* objs[], s32 numObjects)
193 {
194 s32 ret;
195 NN_UTIL_PANIC_IF_FAILED(WaitMultiple(&ret, objs, numObjects, false, WAIT_INFINITE));
196 return ret;
197 }
198
199 }} // namespace nn::os
200
201 #endif // __cplusplus
202
203 // 以下、C 用宣言
204 #include <nn/util/detail/util_CLibImpl.h>
205
206 NN_UTIL_DETAIL_CLIBIMPL_DEFINE_ABSTRACT_BUFFER_CLASS(nnosWaitObject)
207
208 /*!
209 @brief 対応する C++ 関数を参照してください。@ref nn::os::WaitObject::WaitOne
210 */
211 NN_EXTERN_C bool nnosWaitObjectWaitOne(nnosWaitObject* p, s64 nanoSecondsTimeout);
212
213 /*!
214 @brief 対応する C++ 関数を参照してください。@ref nn::os::WaitObject::WaitAll
215 */
216 NN_EXTERN_C bool nnosWaitObjectWaitAll(nnosWaitObject* objs[], s32 numObjects, s64 nanoSecondsTimeout);
217
218 /*!
219 @brief 対応する C++ 関数を参照してください。@ref nn::os::WaitObject::WaitAny
220 */
221 NN_EXTERN_C s32 nnosWaitObjectWaitAny(nnosWaitObject* objs[], s32 numObjects, s64 nanoSecondsTimeout);
222
223 /* NN_OS_SYNCHRONIZATION_H_ */
224 #endif /* NN_OS_OS_SYNCHRONIZATION_H_ */
225