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