1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     os_Thread.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      Thread に関する API の宣言
18 
19     :include nn/os.h
20 */
21 
22 #ifndef NN_OS_OS_THREAD_H_
23 #define NN_OS_OS_THREAD_H_
24 
25 #include <nn/types.h>
26 #include <nn/Handle.h>
27 #include <nn/os/os_Synchronization.h>
28 #include <nn/os/os_Result.h>
29 #include <nn/os/os_Tick.h>
30 #include <nn/os/os_SpinWaitSelect.h>
31 
32 #include <nn/util/util_Result.h>
33 #include <nn/util/util_TypeTraits.h>
34 #include <nn/err.h>
35 
36 /*
37     @def    NN_OS_CORE_NO_ALL
38     @brief 対応する C++ 関数を参照してください。@ref nn::os::CORE_NO_ALL
39 */
40 #define NN_OS_CORE_NO_ALL                           (-1)
41 
42 /*
43     @def    NN_OS_CORE_NO_USE_PROCESS_VALUE
44     @brief 対応する C++ 関数を参照してください。@ref nn::os::CORE_NO_USE_PROCESS_VALUE
45 */
46 #define NN_OS_CORE_NO_USE_PROCESS_VALUE             (-2)
47 
48 #define NN_OS_THREAD_PRIORITY_RANGE_SIZE            32
49 
50 /*
51     @def    NN_OS_LOWEST_THREAD_PRIORITY
52     @brief 対応する C++ 関数を参照してください。@ref nn::os::LOWEST_THREAD_PRIORITY
53 */
54 #define NN_OS_LOWEST_THREAD_PRIORITY                (NN_OS_THREAD_PRIORITY_RANGE_SIZE - 1)
55 
56 /*
57     @def    NN_OS_HIGHEST_THREAD_PRIORITY
58     @brief 対応する C++ 関数を参照してください。@ref nn::os::HIGHEST_THREAD_PRIORITY
59 */
60 #define NN_OS_HIGHEST_THREAD_PRIORITY               0
61 
62 /*
63     @def    NN_OS_DEFAULT_THREAD_PRIORITY
64     @brief 対応する C++ 関数を参照してください。@ref nn::os::DEFAULT_THREAD_PRIORITY
65 */
66 #define NN_OS_DEFAULT_THREAD_PRIORITY               16
67 
68 
69 
70 #ifdef __cplusplus
71 
72 #include <nn/os/os_SvcTypes.autogen.h>
73 
74 namespace nn{ namespace os{
75 
76 namespace detail {
77     s32 ConvertSvcToLibraryPriority(s32 svc);
78     s32 ConvertLibraryToSvcPriority(s32 lib);
79 }
80 
81 /*
82     @brief スレッドの最低優先度を表す定数です。31 です。
83 */
84 const s32 LOWEST_THREAD_PRIORITY = NN_OS_LOWEST_THREAD_PRIORITY;
85 
86 /*
87     @brief スレッドの最高優先度を表す定数です。0 です。
88 */
89 const s32 HIGHEST_THREAD_PRIORITY = NN_OS_HIGHEST_THREAD_PRIORITY;
90 
91 /*
92     @brief デフォルトのスレッド優先度を表す定数です。16 です。
93 */
94 const s32 DEFAULT_THREAD_PRIORITY = NN_OS_DEFAULT_THREAD_PRIORITY;
95 
96 /*
97     @brief スレッドを実行するプロセッサ番号がどれでも良いことを表します。
98 */
99 const s32 CORE_NO_ALL = NN_OS_CORE_NO_ALL;
100 
101 /*
102     @brief スレッドの実行をするプロセッサ番号を指定する際、アプリケーションで設定されているデフォルトの番号を使うことを表します。
103 */
104 const s32 CORE_NO_USE_PROCESS_VALUE = NN_OS_CORE_NO_USE_PROCESS_VALUE;
105 
106 const s32 THREAD_PRIORITY_RANGE_SIZE = NN_OS_THREAD_PRIORITY_RANGE_SIZE;
107 
108 /* @typedef void (*ThreadFunc)(uptr param)
109     @brief スレッドで実行する関数の型を表します。
110 */
111 
112 /*!
113     @brief スレッドを表すクラスです。
114 
115     Bug:   現在の実装では、優先プロセッサやアフィニティマスクの設定はできません。
116 
117            スレッドには優先度があります。
118            スレッド優先度には 0~31 までの整数で指定することができ、0 が一番高い優先度を表します。
119            標準的なスレッドは @ref DEFAULT_THREAD_PRIORITY (16)を指定します。
120 
121            スレッドの動作にはスタック領域が必要ですが、
122            スタック領域の管理は、自分で管理することもライブラリに任せることもできます。
123 
124            自分でスタック領域を管理する場合は @ref Start 関数にスタック領域を渡し、スレッドを開始します。
125            スタック領域は uptr GetStackBottom() 関数を持つようなクラスのインスタンスを渡します。
126            @ref StackMemoryBlock や @ref StackBuffer はこの条件を満たすクラスのため、直接渡すことができます。
127            自分でスタック領域を管理する場合は、
128            スレッドが終了する前にスタック領域が無効になる(解放されるなど)ことがないように十分に注意してください。
129 
130            ライブラリにスタック領域の管理を任せる場合は @ref StartUsingAutoStack 関数にスタックサイズを渡し、スレッドを開始します。
131            ライブラリが確保するスタック領域のサイズは4096byte単位です。
132 
133            スレッドオブジェクトが有効になるのは Start 系関数から抜けた後です。
134            スレッドが走り出した時点ではないことに注意してください。
135            オブジェクトが有効かどうかは IsValid 関数で取得することができます。
136 
137            @ref Start によって開始された Thread オブジェクトを破棄する前には、
138            必ず明示的に @ref Joinを呼ぶ必要があります。
139            @ref Detach を呼ぶことはできません。
140 
141            @ref StartUsingAutoStack によって開始された Thread オブジェクトを破棄する前には、
142            必ず明示的に @ref Join か @ref Detach を呼ぶ必要があります。
143 
144            Thread オブジェクトは @ref WaitObject を継承しており、Wait 動作の解放はスレッドの終了を意味します。
145            @ref Join 動作をブロック無しに行う必要がある際は、
146            先に @ref WaitOne や @ref WaitObject::WaitAny などを呼んで Wait 動作の解放を確認しておきます。
147 
148            ※現在の実装では優先プロセッサやアフィニティマスクをスレッド開始時以外に指定することはできません。
149 
150            スレッドには、優先プロセッサおよびアフィニティマスクを指定することができます。
151            優先プロセッサには、0 ~ (コア数-1) まで指定することができます。
152            また、@ref CORE_NO_ALL を指定すると全てのプロセッサを平等に扱うように優先プロセッサを設定し、
153            全てのプロセッサを含むアフィニティマスクを使用します。
154            @ref CORE_NO_USE_PROCESS_VALUE を指定すると、所属するアプリケーションのデフォルトの値を使用します。
155            優先プロセッサを指定すると、スレッドは指定されたプロセッサ上で優先して動作しますが、
156            必ずしも指定どおりのプロセッサ上で動作するわけではありません。
157 
158            アフィニティマスクは、スレッドがどのプロセッサ上で実行されるべきかを指定するものです。
159            bit8の配列で表現し、各要素は下位1ビット目が最初のプロセッサを表します。
160            ビットを1にすることで、対象のプロセッサで走行する許可を与えます。
161            必ず、どれかのプロセッサをしてする必要があり、全てのビット0にしたマスクを指定することはできません。
162 
163            スレッドの開始時には優先プロセッサを指定することができますが、
164            ここでプロセッサ番号を指定した場合、
165            スレッド開始時のアフィニティマスクはそのプロセッサ番号のみが指定されたことになります。
166 */
167 
168 class Thread : public WaitObject
169 {
170 public:
171     class AutoStackManager
172     {
173     public:
174         virtual void* Construct(size_t stackSize) = 0;
175         virtual void Destruct(void* pStackBottom, bool isError) = 0;
176     };
177 
178 public:
179 
180     /*!
181     @brief        コンストラクタです。
182 
183                   スレッドを開始するには、@ref Start または @ref TryStart を使います。
184     */
Thread()185     Thread() : m_CanFinalize(true) {}
186 
187     /*!
188     @brief        デストラクタ
189 
190                   スレッドオブジェクトを破棄します。
191                   破棄時の注意は @ref Finalize を参照してください。
192     */
193     ~Thread();
194 
195     /*!
196     @brief        スレッドを初期化し実行します。
197 
198                   ユーザが用意したスタックを使ってスレッドを初期化し、スレッドを開始します。
199                   スレッドの終了が確認されるまで、スタック領域は維持されている必要があります。
200 
201     @param[in]    f             実行を開始する関数へのポインタ
202     @param[in]    stack         スタック領域を表すオブジェクト
203     @param[in]    priority      スレッドの優先度
204     @param[in]    coreNo        スレッドの優先プロセッサ
205 
206     @tparam       Stack         スタックを表す型
207 
208     @return       無し。
209 
210     :overload partialtemplate
211     */
212     template <typename Stack>
213     void Start(void (*f)(), Stack& stack, s32 priority = DEFAULT_THREAD_PRIORITY, s32 coreNo = CORE_NO_USE_PROCESS_VALUE);
214 
215     /*!
216     @brief        スレッドを初期化し実行します。
217 
218                   ユーザが用意したスタックを使ってスレッドを初期化し、スレッドを開始します。
219                   スレッドの終了が確認されるまで、スタック領域は維持されている必要があります。
220 
221     @param[in]    f             実行を開始する関数へのポインタ
222     @param[in]    param         実行を開始する関数へ渡す引数
223     @param[in]    stack         スタック領域を表すオブジェクト
224     @param[in]    priority      スレッドの優先度
225     @param[in]    coreNo        スレッドの優先プロセッサ
226 
227     @tparam       T             実行する関数の引数の型(コピーできる型である必要があります)
228     @tparam       U             T に変換できる型
229     @tparam       Stack         スタックを表す型
230 
231     @return       無し。
232 
233     :overload fulltemplate
234     */
235     template <typename T, typename U, typename Stack>
236     void Start(void (*f)(T), U param, Stack& stack, s32 priority = DEFAULT_THREAD_PRIORITY, s32 coreNo = CORE_NO_USE_PROCESS_VALUE);
237     template <typename T, typename Stack>
238     void Start(void (*f)(const T*), const T& param, Stack& stack, s32 priority = DEFAULT_THREAD_PRIORITY, s32 coreNo = CORE_NO_USE_PROCESS_VALUE);
239     template <typename T, typename Stack>
240     void Start(void (*f)(const T&), const T& param, Stack& stack, s32 priority = DEFAULT_THREAD_PRIORITY, s32 coreNo = CORE_NO_USE_PROCESS_VALUE);
241 
242     /*!
243     @brief        スレッドの初期化と実行を試みます。
244 
245                   スレッドを初期化し実行をしますが、
246                   リソース不足などが原因で失敗した場合にエラーを返します。
247 
248     @sa Start
249 
250     @param[in]    f             実行を開始する関数へのポインタ
251     @param[in]    stack         スタック領域を表すオブジェクト
252     @param[in]    priority      スレッドの優先度
253     @param[in]    coreNo        スレッドの優先プロセッサおよびアフィニティマスクの指定
254 
255     @tparam       Stack         スタックを表す型
256 
257     @return       関数の実行結果を返します。
258     */
259     template <typename Stack>
260     nn::Result TryStart(void (*f)(), Stack& stack, s32 priority = DEFAULT_THREAD_PRIORITY, s32 coreNo = CORE_NO_USE_PROCESS_VALUE);
261 
262     /*!
263     @brief        スレッドの初期化と実行を試みます。
264 
265                   スレッドを初期化し実行をしますが、
266                   リソース不足などが原因で失敗した場合にエラーを返します。
267 
268     @sa Start
269 
270     @param[in]    f             実行を開始する関数へのポインタ
271     @param[in]    param         実行を開始する関数へ渡す引数
272     @param[in]    stack         スタック領域を表すオブジェクト
273     @param[in]    priority      スレッドの優先度
274     @param[in]    coreNo        スレッドの優先プロセッサおよびアフィニティマスクの指定
275 
276     @tparam       T             実行する関数の引数の型(コピーできる型である必要があります)
277     @tparam       U             T に変換できる型
278     @tparam       Stack         スタックを表す型
279 
280     @return       関数の実行結果を返します。
281     */
282     template <typename T, typename U, typename Stack>
283     nn::Result TryStart(void (*f)(T), U param, Stack& stack, s32 priority = DEFAULT_THREAD_PRIORITY, s32 coreNo = CORE_NO_USE_PROCESS_VALUE);
284 
285     /*!
286     @brief        スレッドを初期化し実行します。
287 
288                   スタックは指定されたサイズ以上のサイズに自動的に確保され、
289                   スレッド終了時に自動的に破棄されます。
290 
291     @param[in]    f             実行を開始する関数へのポインタ
292     @param[in]    stackSize     スタックサイズ
293     @param[in]    priority      スレッドの優先度
294     @param[in]    coreNo        スレッドの優先プロセッサおよびアフィニティマスクの指定
295 
296     @return       無し。
297     */
298     void StartUsingAutoStack(void (*f)(), size_t stackSize, s32 priority = DEFAULT_THREAD_PRIORITY, s32 coreNo = CORE_NO_USE_PROCESS_VALUE);
299 
300     /*!
301     @brief        スレッドを初期化し実行します。
302 
303                   スタックは指定されたサイズ以上のサイズに自動的に確保され、
304                   スレッド終了時に自動的に破棄されます。
305 
306     @param[in]    f             実行を開始する関数へのポインタ
307     @param[in]    param         実行を開始する関数へ渡す引数
308     @param[in]    stackSize     スタックサイズ
309     @param[in]    priority      スレッドの優先度
310     @param[in]    coreNo        スレッドの優先プロセッサおよびアフィニティマスクの指定
311 
312     @tparam       T             実行する関数の引数の型(コピーできる型である必要があります)
313     @tparam       U             T に変換できる型
314 
315     @return       無し。
316     */
317     template <typename T, typename U>
318     void StartUsingAutoStack(void (*f)(T), U param, size_t stackSize, s32 priority = DEFAULT_THREAD_PRIORITY, s32 coreNo = CORE_NO_USE_PROCESS_VALUE);
319 
320     /*!
321     :overload notemplate
322 
323     @brief        スレッドの初期化と実行を試みます。
324 
325                   スレッドを初期化し実行をしますが、
326                   リソース不足などが原因で失敗した場合にエラーを返します。
327 
328     @sa StartUsingAutoStack
329 
330     @param[in]    f             実行を開始する関数へのポインタ
331     @param[in]    stackSize     スタックサイズ
332     @param[in]    priority      スレッドの優先度
333     @param[in]    coreNo        スレッドの優先プロセッサおよびアフィニティマスクの指定
334 
335     @return       関数の実行結果を返します。
336     */
337     nn::Result TryStartUsingAutoStack(void (*f)(), size_t stackSize, s32 priority = DEFAULT_THREAD_PRIORITY, s32 coreNo = CORE_NO_USE_PROCESS_VALUE);
338 
339     /*!
340     :overload template
341 
342     @brief        スレッドの初期化と実行を試みます。
343 
344                   スレッドを初期化し実行をしますが、
345                   リソース不足などが原因で失敗した場合にエラーを返します。
346 
347     @sa StartUsingAutoStack
348 
349     @param[in]    f             実行を開始する関数へのポインタ
350     @param[in]    param         実行を開始する関数へ渡す引数
351     @param[in]    stackSize     スタックサイズ
352     @param[in]    priority      スレッドの優先度
353     @param[in]    coreNo        スレッドの優先プロセッサおよびアフィニティマスクの指定
354 
355     @tparam       T             実行する関数の引数の型(コピーできる型である必要があります)
356     @tparam       U             T に変換できる型
357 
358     @return       関数の実行結果を返します。
359     */
360     template <typename T, typename U>
361     nn::Result TryStartUsingAutoStack(void (*f)(T), U param, size_t stackSize, s32 priority = DEFAULT_THREAD_PRIORITY, s32 coreNo = CORE_NO_USE_PROCESS_VALUE);
362 
363     /*!
364     @brief        スレッドオブジェクトを破棄します。
365 
366                   スレッドを破棄する前に、必ず @ref Detach か @ref Join を呼んでいる必要があります。
367                   呼んでいなかった場合、PANIC します。
368 
369 
370     @return       無し。
371     */
372     void Finalize();
373 
374     /*!
375     @brief        スレッドの終了を待ちます。
376 
377                   この関数はスレッドの終了を無条件で待ちます。
378                   タイムアウトつきで待つなど、細かい制御が必要な場合は、
379                   @ref WaitObject にある関数を使ってスレッドの終了を待った後、
380                   この関数を呼び出すようにしてください。
381 
382     @return       無し。
383     */
384     void Join();
385 
386     /*!
387     @brief        スレッドのデタッチを行います。
388 
389                   このオブジェクトがスレッドに対して今後一切の操作を行わないことを宣言します。
390                   このオブジェクトに対しては、@ref Finalize とデストラクタ以外を呼ぶことができなくなります。
391 
392                   @ref Start を使って開始したスレッドに対してこの関数を呼ぶことはできません。
393 
394     @return       無し。
395     */
396     void Detach();
397 
398     /*!
399     @brief        スレッドが生きているかどうかを取得します。
400 
401     @return       スレッドが生きているならtrue、そうでないならfalseを返します。
402     */
IsAlive()403     bool IsAlive() const { return !const_cast<Thread*>(this)->WaitOne(0); }
404 
405     /*!
406     @brief        カレントスレッドを指定時間だけ休止状態にします。
407 
408     @param[in]    span  休止する時間
409 
410     @return       無し。
411     */
412     static void Sleep(nn::fnd::TimeSpan span);
413 
414     /*!
415     @brief        カレントスレッドと同じ優先度のスレッドに実行機会を与えます。
416 
417                   スケジューラは優先度スケジューリングを行いますので
418                   常に実行可能なスレッドの中で最高優先度のスレッドが動作しています。
419                   最高優先度のスレッドが複数存在する場合、
420                   スケジューラはカレントスレッドを継続して動作させようと試みますので
421                   通常はカレントスレッドが実行可能でなくならない限り
422                   同優先度の他のスレッドは実行されません。
423 
424                   この関数はカレントスレッドを実行可能としたまま
425                   同優先度の他のスレッドに実行権を明け渡します。
426                   同優先度のスレッドが存在しない場合は何も起りません。
427 
428     @return       無し。
429     */
430     static void Yield();
431 
432     // スレッドの状態の取得・設定
433     // 非 static メンバ関数は、インスタンスに対して作用する。
434     // "Current" を含む名前の static メンバ関数は、カレントスレッドに対して作用する。
435     // "Default" を含む名前の static メンバ関数は、CreateThread で coreNo = CORE_NO_USE_PROCESS_VALUE のとき、
436     // 作成されるスレッドの属性のデフォルト値に作用する。
437 
438     // コンテキストの取得
439     //   TODO: 未実装
440     // void GetContext(nn::os::ThreadContext* pContext) const;
441     // static void GetCurrentContext(nn::os::ThreadContext* pContext);
442 
443     /*!
444     @brief        インスタンスのスレッドのスレッド ID を取得します。
445 
446     @return       インスタンスのスレッドのスレッド ID を返します。
447     */
448     bit32 GetId() const;
449 
450     /*!
451     @brief        カレントスレッドのスレッド ID を取得します。
452 
453     @return       カレントスレッドのスレッド ID を返します。
454     */
455     static bit32 GetCurrentId();
456 
457     /*!
458     @brief        インスタンスのスレッドの優先度を取得します。
459 
460     @return       インスタンスのスレッドの優先度を返します。
461     */
462     s32 GetPriority() const;
463 
464     /*!
465     @brief        カレントスレッドの優先度を取得します。
466 
467     @return       カレントスレッドの優先度を返します。
468     */
469     static s32 GetCurrentPriority();
470 
471     /*!
472     @brief        インスタンスのスレッドの優先度を設定します。
473 
474     @param[in]    priority  スレッドの優先度を指定します。
475 
476     @return       無し。
477     */
478     void ChangePriority(s32 priority);
479 
480     /*!
481     @brief        カレントスレッドの優先度を設定します。
482 
483     @param[in]    priority  スレッドの優先度を指定します。
484 
485     @return       無し。
486     */
487     static void ChangeCurrentPriority(s32 priority);
488 
489     // スレッド Affinity の設定・取得
490     //   AffinityMask は構造体やクラスで包む?
491     /*!
492     @brief        インスタンスのアフィニティマスクを取得します。
493 
494     @param[out]   pAffinityMask     取得したアフィニティマスクを格納するバッファを指定します。
495     @param[in]    numProcessor      pAffinityMask が指すバッファのビット数を指定します。
496 
497     @return       無し。
498 
499     Bug:          この関数は未実装です。この関数を使わないでください。
500     */
501     void GetAffinityMask(bit8* pAffinityMask, s32 numProcessor) const;
502 
503     /*!
504     @brief        カレントスレッドのアフィニティマスクを取得します。
505 
506     @param[out]   pAffinityMask     取得したアフィニティマスクを格納するバッファを指定します。
507     @param[in]    numProcessor      pAffinityMask が指すバッファのビット数を指定します。
508 
509     @return       無し。
510 
511     Bug:          この関数は未実装です。この関数を使わないでください。
512     */
513     static void GetCurrentAffinityMask(bit8* pAffinityMask, s32 numProcessor);
514 
515     /*!
516     @brief        coreNo = CORE_NO_USE_PROCESS_VALUE で作成されるスレッドのアフィニティマスクを取得します。
517 
518     @param[out]   pAffinityMask     取得したアフィニティマスクを格納するバッファを指定します。
519     @param[in]    numProcessor      pAffinityMask が指すバッファのビット数を指定します。
520 
521     @return       無し。
522 
523     Bug:          この関数は未実装です。この関数を使わないでください。
524     */
525     static void GetDefaultAffinityMask(bit8* pAffinityMask, s32 numProcessor);
526 
527     /*!
528     @brief        インスタンスのアフィニティマスクを設定します。
529 
530     @param[in]    pAffinityMask    新しく設定するアフィニティマスクを指定します。
531     @param[in]    numProcessor     pAffinityMask が指すビット列の有効なビット数を指定します。
532 
533     @return       無し。
534 
535     Bug:          この関数は未実装です。この関数を使わないでください。
536     */
537     void ChangeAffinityMask(const bit8* pAffinityMask, s32 numProcessor);
538 
539     /*!
540     @brief        カレントスレッドのアフィニティマスクを設定します。
541 
542     @param[in]    pAffinityMask    新しく設定するアフィニティマスクを指定します。
543     @param[in]    numProcessor     pAffinityMask が指すビット列の有効なビット数を指定します。
544 
545     @return       無し。
546 
547     Bug:          この関数は未実装です。この関数を使わないでください。
548     */
549     static void ChangeCurrentAffinityMask(const bit8* pAffinityMask, s32 numProcessor);
550 
551     /*!
552     @brief        coreNo = CORE_NO_USE_PROCESS_VALUE で作成されるスレッドのアフィニティマスクを設定します。
553 
554     @param[in]    pAffinityMask     新しく設定するアフィニティマスクを指定します。
555     @param[in]    numProcessor     pAffinityMask が指すビット列の有効なビット数を指定します。
556 
557     @return       無し。
558 
559     Bug:          この関数は未実装です。この関数を使わないでください。
560     */
561     static void SetDefaultAffinityMask(const bit8* pAffinityMask, s32 numProcessor);
562 
563     // IdealProcessor の取得・設定
564     /*!
565     @brief        インスタンスの優先プロセッサ番号を取得します。
566 
567     @return       優先プロセッサ番号を返します。
568 
569     Bug:          この関数は未実装です。この関数を使わないでください。
570     */
571     s32 GetIdealProcessor() const;
572 
573     /*!
574     @brief        カレントスレッドの優先プロセッサ番号を取得します。
575 
576     @return       優先プロセッサ番号を返します。
577 
578     Bug:          この関数は未実装です。この関数を使わないでください。
579     */
580     static s32 GetCurrentIdealProcessor();
581 
582     /*!
583     @brief        coreNo = CORE_NO_USE_PROCESS_VALUE で作成されるスレッドの優先プロセッサ番号を取得します。
584 
585     @return       優先プロセッサ番号を返します。
586 
587     Bug:          この関数は未実装です。この関数を使わないでください。
588     */
589     static s32 GetDefaultIdealProcessor();
590 
591     /*!
592     @brief        インスタンスの優先プロセッサ番号を設定します。
593 
594     @param[in]    coreNo     優先プロセッサ番号
595 
596     @return       無し。
597 
598     Bug:          この関数は未実装です。この関数を使わないでください。
599     */
600     void ChangeIdealProcessor(s32 coreNo);
601 
602     /*!
603     @brief        カレントスレッドの優先プロセッサ番号を設定します。
604 
605     @param[in]    coreNo     優先プロセッサ番号
606 
607     @return       無し。
608 
609     Bug:          この関数は未実装です。この関数を使わないでください。
610     */
611     static void ChangeCurrentIdealProcessor(s32 coreNo);
612 
613     /*!
614     @brief        coreNo = CORE_NO_USE_PROCESS_VALUE で作成されるスレッドの IdealProcessor を設定します。
615 
616     @param[in]    coreNo     優先プロセッサ番号
617 
618     @return       無し。
619 
620     Bug:          この関数は未実装です。この関数を使わないでください。
621     */
622     static void SetDefaultIdealProcessor(s32 coreNo);
623 
624     /*!
625     @brief        カレントスレッドの動作しているプロセッサ番号の取得
626 
627     @return       カレントスレッドの動作しているプロセッサ番号を返します。
628 
629     Bug:          この関数は未実装です。この関数を使わないでください。
630     */
631     static s32 GetCurrentProcessorNumber();
632 
633     /*!
634     @brief        メインスレッドを表すオブジェクトを取得します。
635     @return       メインスレッドを表すオブジェクト。
636     */
GetMainThread()637     static Thread& GetMainThread() { return s_MainThread; }
638 
639     static void SetAutoStackManager(AutoStackManager* pManager);
640 
641 
642 private:
643     struct InitializeAsCurrentTag {};
644     struct TypeInfo;
645     struct FunctionInfo;
646 
647 private:
648     bool        m_CanFinalize;
649     bool        m_UsingAutoStack;
650     NN_PADDING2;
651 
652     static Thread               s_MainThread;
653     static AutoStackManager*    s_pAutoStackManager;
654 
655 private:
656     Thread(const InitializeAsCurrentTag&);
657     void FinalizeImpl();
658 
659     Result TryInitializeAndStartImpl(const TypeInfo& typeInfo, ThreadFunc f, const void* p, uptr stackBottom, s32 priority, s32 coreNo, bool isAutoStack);
660     Result TryInitializeAndStartImplUsingAutoStack(const TypeInfo& typeInfo, ThreadFunc f, const void* p, size_t stackSize, s32 priority, s32 coreNo);
661 
662 private:
663     static void OnThreadStart();
664     static void OnThreadExit();
665 
666     static void ThreadStart(uptr);
667     static void ThreadStartUsingAutoStack(uptr);
668     static void NoParameterFunc(void (*)());
669     static void SleepImpl(nn::fnd::TimeSpan span);
670 
671     static void CallDestructorAndExit(void* pStackBottom);
672 };
673 
674 /*!
675     @brief スレッド用のスタックを、static 領域や構造体の中などに配置したい場合に使うクラステンプレートです。
676 
677            @ref GetStackBottom 関数の戻り値を @ref Thread::Start 関数などに渡すことで、
678            スレッドのスタックとしてこの領域を使用することができます。
679 
680     @tparam Size スタックのサイズを表します。
681 */
682 template <size_t Size>
683 class StackBuffer
684 {
685 private:
686     typename nn::util::aligned_storage<Size, 8>::type m_Buffer;
687 public:
688 
689     /*!
690     @brief        スタックの底アドレスを返します。
691 
692     @return       スタックの底アドレス。
693     */
GetStackBottom()694     uptr GetStackBottom() const { return reinterpret_cast<uptr>(this + 1); }
695 
696     void MarkCanary(bit32 value = 0xDEADBEEF) { reinterpret_cast<bit32*>(this)[0] = value; }
697     bool CheckCanary(bit32 value = 0xDEADBEEF) const { return reinterpret_cast<const bit32*>(this)[0] == value; }
698 };
699 
700 }}
701 
702 // インライン実装
703 
704 #ifdef NN_SYSTEM_PROCESS
705 
706 #include <new>
707 
708 #include <nn/dbg/dbg_Logger.h>
709 
710 namespace nn { namespace os {
711 
712 struct Thread::TypeInfo
713 {
714 private:
715 
716     template <typename T, typename U>
CopyTypeInfo717     static void Copy(const void* src, void* dst)
718     {
719         new (dst) T(*reinterpret_cast<const U*>(src));
720     }
721     template <typename T>
CopyTypeInfo722     static void Copy(const void* src, void* dst)
723     {
724         new (dst) T(*reinterpret_cast<const T*>(src));
725     }
726 
727     template <typename T>
DestroyTypeInfo728     static void Destroy(void* p)
729     {
730         reinterpret_cast<T*>(p)->~T();
731     }
732 
733     template <typename T>
InvokeTypeInfo734     static void Invoke(ThreadFunc f, const void* p)
735     {
736         (*reinterpret_cast<void (*)(T)>(f))(*reinterpret_cast<const T*>(p));
737     }
738     template <typename T>
Invoke2TypeInfo739     static void Invoke2(ThreadFunc f, const void* p)
740     {
741         (*reinterpret_cast<void (*)(const T*)>(f))(reinterpret_cast<const T*>(p));
742     }
743 
744 public:
745 
746     size_t size;
747     void (*copy)(const void* src, void* dst);
748     void (*destroy)(void* p);
749     void (*invoke)(ThreadFunc f, const void* p);
750 
751     template <typename T, typename U>
752     void SetData(typename nn::util::enable_if<nn::util::is_convertible<U, T>::value>::type* = 0)
753     {
754         this->size = sizeof(T);
755         this->copy = &(Copy<T, U>);
756         this->destroy = &(Destroy<T>);
757         this->invoke = &(Invoke<T>);
758     }
759     template <typename T>
SetDataTypeInfo760     void SetData()
761     {
762         this->size = sizeof(T);
763         this->copy = &(Copy<T>);
764         this->destroy = &(Destroy<T>);
765         this->invoke = &(Invoke2<T>);
766     }
767 
768 };
769 
770 template <typename T, typename U, typename Stack>
Start(void (* f)(T),U param,Stack & stack,s32 priority,s32 coreNo)771 inline void Thread::Start(void (*f)(T), U param, Stack& stack, s32 priority, s32 coreNo)
772 {
773     TypeInfo info;
774     info.SetData<T, U>();
775     NN_ERR_THROW_FATAL(TryInitializeAndStartImpl(info, reinterpret_cast<ThreadFunc>(f), &param, stack.GetStackBottom(), priority, coreNo, false));
776 }
777 
778 template <typename T, typename Stack>
Start(void (* f)(const T *),const T & param,Stack & stack,s32 priority,s32 coreNo)779 inline void Thread::Start(void (*f)(const T*), const T& param, Stack& stack, s32 priority, s32 coreNo)
780 {
781     TypeInfo info;
782     info.SetData<T>();
783     NN_ERR_THROW_FATAL(TryInitializeAndStartImpl(info, reinterpret_cast<ThreadFunc>(f), &param, stack.GetStackBottom(), priority, coreNo, false));
784 }
785 
786 template <typename Stack>
Start(void (* f)(),Stack & stack,s32 priority,s32 coreNo)787 inline void Thread::Start(void (*f)(), Stack& stack, s32 priority, s32 coreNo)
788 {
789     Start(NoParameterFunc, f, stack, priority, coreNo);
790 }
791 
792 template <typename T, typename U, typename Stack>
TryStart(void (* f)(T),U param,Stack & stack,s32 priority,s32 coreNo)793 inline nn::Result Thread::TryStart(void (*f)(T), U param, Stack& stack, s32 priority, s32 coreNo)
794 {
795     TypeInfo info;
796     info.SetData<T, U>();
797     Result result = TryInitializeAndStartImpl(info, reinterpret_cast<ThreadFunc>(f), &param, stack.GetStackBottom(), priority, coreNo, false);
798     if (result.GetSummary() == Result::SUMMARY_OUT_OF_RESOURCE)
799     {
800         return result;
801     }
802     NN_ERR_THROW_FATAL(result);
803     return result;
804 }
805 
806 template <typename Stack>
TryStart(void (* f)(),Stack & stack,s32 priority,s32 coreNo)807 inline nn::Result Thread::TryStart(void (*f)(), Stack& stack, s32 priority, s32 coreNo)
808 {
809     return TryStart(NoParameterFunc, f, stack, priority, coreNo);
810 }
811 
812 template <typename T, typename U>
StartUsingAutoStack(void (* f)(T),U param,size_t stackSize,s32 priority,s32 coreNo)813 inline void Thread::StartUsingAutoStack(void (*f)(T), U param, size_t stackSize, s32 priority, s32 coreNo)
814 {
815     TypeInfo info;
816     info.SetData<T, U>();
817     NN_ERR_THROW_FATAL(TryInitializeAndStartImplUsingAutoStack(info, reinterpret_cast<ThreadFunc>(f), &param, stackSize, priority, coreNo));
818 }
819 
StartUsingAutoStack(void (* f)(),size_t stackSize,s32 priority,s32 coreNo)820 inline void Thread::StartUsingAutoStack(void (*f)(), size_t stackSize, s32 priority, s32 coreNo)
821 {
822     StartUsingAutoStack(NoParameterFunc, f, stackSize, priority, coreNo);
823 }
824 
825 template <typename T, typename U>
TryStartUsingAutoStack(void (* f)(T),U param,size_t stackSize,s32 priority,s32 coreNo)826 inline nn::Result Thread::TryStartUsingAutoStack(void (*f)(T), U param, size_t stackSize, s32 priority, s32 coreNo)
827 {
828     TypeInfo info;
829     info.SetData<T, U>();
830     Result result = TryInitializeAndStartImplUsingAutoStack(info, reinterpret_cast<ThreadFunc>(f), &param, stackSize, priority, coreNo);
831     if (result.GetSummary() == Result::SUMMARY_OUT_OF_RESOURCE)
832     {
833         return result;
834     }
835     NN_ERR_THROW_FATAL(result);
836     return result;
837 }
838 
TryStartUsingAutoStack(void (* f)(),size_t stackSize,s32 priority,s32 coreNo)839 inline nn::Result Thread::TryStartUsingAutoStack(void (*f)(), size_t stackSize, s32 priority, s32 coreNo)
840 {
841     return TryStartUsingAutoStack(NoParameterFunc, f, stackSize, priority, coreNo);
842 }
843 
FinalizeImpl()844 inline void Thread::FinalizeImpl()
845 {
846     if (!m_CanFinalize)
847     {
848         NN_TPANIC_("Thread is not Joined or Detached either.");
849     }
850 }
851 
Finalize()852 inline void Thread::Finalize()
853 {
854     FinalizeImpl();
855     this->WaitObject::Finalize();
856 }
857 
~Thread()858 inline Thread::~Thread()
859 {
860     FinalizeImpl();
861 }
862 
Join()863 inline void Thread::Join()
864 {
865     this->WaitOne();
866     this->m_CanFinalize = true;
867 }
868 
Detach()869 inline void Thread::Detach()
870 {
871     NN_TASSERT_(m_UsingAutoStack);
872     this->m_CanFinalize = true;
873     Finalize();
874 }
875 
Sleep(nn::fnd::TimeSpan span)876 inline void Thread::Sleep(nn::fnd::TimeSpan span)
877 {
878     SleepImpl(span);
879 }
880 
Yield()881 inline void Thread::Yield()
882 {
883     nn::svc::SleepThread(0);
884 }
885 
GetId()886 inline bit32 Thread::GetId() const
887 {
888     bit32 ret;
889     NN_ERR_THROW_FATAL(nn::svc::GetThreadId(&ret, GetHandle()));
890     return ret;
891 }
892 
GetCurrentId()893 inline bit32 Thread::GetCurrentId()
894 {
895     bit32 ret;
896     NN_ERR_THROW_FATAL(nn::svc::GetThreadId(&ret, PSEUDO_HANDLE_CURRENT_THREAD));
897     return ret;
898 }
899 
GetPriority()900 inline s32 Thread::GetPriority() const
901 {
902     s32 ret;
903     NN_ERR_THROW_FATAL(nn::svc::GetThreadPriority(&ret, GetHandle()));
904     return os::detail::ConvertSvcToLibraryPriority(ret);
905 }
906 
GetCurrentPriority()907 inline s32 Thread::GetCurrentPriority()
908 {
909     s32 ret;
910     NN_ERR_THROW_FATAL(nn::svc::GetThreadPriority(&ret, PSEUDO_HANDLE_CURRENT_THREAD));
911     return os::detail::ConvertSvcToLibraryPriority(ret);
912 }
913 
ChangePriority(s32 priority)914 inline void Thread::ChangePriority(s32 priority)
915 {
916     NN_ERR_THROW_FATAL(nn::svc::SetThreadPriority(GetHandle(), os::detail::ConvertLibraryToSvcPriority(priority)));
917 }
918 
ChangeCurrentPriority(s32 priority)919 inline void Thread::ChangeCurrentPriority(s32 priority)
920 {
921     NN_ERR_THROW_FATAL(nn::svc::SetThreadPriority(PSEUDO_HANDLE_CURRENT_THREAD, os::detail::ConvertLibraryToSvcPriority(priority)));
922 }
923 
GetAffinityMask(bit8 * pAffinityMask,s32 numProcessor)924 inline void Thread::GetAffinityMask(bit8* pAffinityMask, s32 numProcessor) const
925 {
926     NN_ERR_THROW_FATAL(nn::svc::GetThreadAffinityMask(pAffinityMask, GetHandle(), numProcessor));
927 }
928 
GetCurrentAffinityMask(bit8 * pAffinityMask,s32 numProcessor)929 inline void Thread::GetCurrentAffinityMask(bit8* pAffinityMask, s32 numProcessor)
930 {
931     NN_ERR_THROW_FATAL(nn::svc::GetThreadAffinityMask(pAffinityMask, PSEUDO_HANDLE_CURRENT_THREAD, numProcessor));
932 }
933 
GetDefaultAffinityMask(bit8 * pAffinityMask,s32 numProcessor)934 inline void Thread::GetDefaultAffinityMask(bit8* pAffinityMask, s32 numProcessor)
935 {
936     NN_ERR_THROW_FATAL(nn::svc::GetProcessAffinityMask(pAffinityMask, PSEUDO_HANDLE_CURRENT_PROCESS, numProcessor));
937 }
938 
ChangeAffinityMask(const bit8 * pAffinityMask,s32 numProcessor)939 inline void Thread::ChangeAffinityMask(const bit8* pAffinityMask, s32 numProcessor)
940 {
941     NN_ERR_THROW_FATAL(nn::svc::SetThreadAffinityMask(GetHandle(), pAffinityMask, numProcessor));
942 }
943 
ChangeCurrentAffinityMask(const bit8 * pAffinityMask,s32 numProcessor)944 inline void Thread::ChangeCurrentAffinityMask(const bit8* pAffinityMask, s32 numProcessor)
945 {
946     NN_ERR_THROW_FATAL(nn::svc::SetThreadAffinityMask(PSEUDO_HANDLE_CURRENT_THREAD, pAffinityMask, numProcessor));
947 }
948 
SetDefaultAffinityMask(const bit8 * pAffinityMask,s32 numProcessor)949 inline void Thread::SetDefaultAffinityMask(const bit8* pAffinityMask, s32 numProcessor)
950 {
951     NN_ERR_THROW_FATAL(nn::svc::SetProcessAffinityMask(PSEUDO_HANDLE_CURRENT_PROCESS, pAffinityMask, numProcessor));
952 }
953 
GetIdealProcessor()954 inline s32 Thread::GetIdealProcessor() const
955 {
956     s32 ret;
957     NN_ERR_THROW_FATAL(nn::svc::GetThreadIdealProcessor(&ret, GetHandle()));
958     return ret;
959 }
960 
GetCurrentIdealProcessor()961 inline s32 Thread::GetCurrentIdealProcessor()
962 {
963     s32 ret;
964     NN_ERR_THROW_FATAL(nn::svc::GetThreadIdealProcessor(&ret, PSEUDO_HANDLE_CURRENT_THREAD));
965     return ret;
966 }
967 
GetDefaultIdealProcessor()968 inline s32 Thread::GetDefaultIdealProcessor()
969 {
970     s32 ret;
971     NN_ERR_THROW_FATAL(nn::svc::GetProcessIdealProcessor(&ret, PSEUDO_HANDLE_CURRENT_PROCESS));
972     return ret;
973 }
974 
ChangeIdealProcessor(s32 coreNo)975 inline void Thread::ChangeIdealProcessor(s32 coreNo)
976 {
977     NN_ERR_THROW_FATAL(nn::svc::SetThreadIdealProcessor(GetHandle(), coreNo));
978 }
979 
ChangeCurrentIdealProcessor(s32 coreNo)980 inline void Thread::ChangeCurrentIdealProcessor(s32 coreNo)
981 {
982     NN_ERR_THROW_FATAL(nn::svc::SetThreadIdealProcessor(PSEUDO_HANDLE_CURRENT_THREAD, coreNo));
983 }
984 
SetDefaultIdealProcessor(s32 coreNo)985 inline void Thread::SetDefaultIdealProcessor(s32 coreNo)
986 {
987     NN_ERR_THROW_FATAL(nn::svc::SetProcessIdealProcessor(PSEUDO_HANDLE_CURRENT_PROCESS, coreNo));
988 }
989 
GetCurrentProcessorNumber()990 inline s32 Thread::GetCurrentProcessorNumber()
991 {
992     return nn::svc::GetCurrentProcessorNumber();
993 }
994 
995 
996 /*!
997   @}
998 */
999 /*!
1000   @}
1001 */
1002 
1003 }} // namespace nn::os
1004 
1005 #endif // NN_SYSTEM_PROCESS
1006 
1007 #endif // __cplusplus
1008 
1009 // 以下、C 用宣言
1010 
1011 #include <nn/util/detail/util_CLibImpl.h>
1012 
1013 
1014 /*!
1015   @addtogroup   nn_os               os
1016   @{
1017 
1018   @defgroup     nn_os_Thread_c    Thread (C)
1019 
1020   @brief        @ref nn::os::Thread の C インタフェースモジュールです。
1021 
1022   @{
1023 */
1024 
1025 /*!
1026   @struct       nnosThread
1027   @brief        スレッドを表す C の構造体です。
1028 
1029   @brief 対応するクラス @ref nn::os::Thread を参照してください。
1030 */
1031 NN_UTIL_DETAIL_CLIBIMPL_DEFINE_BUFFER_CLASS(nnosThread, nn::os::Thread, 8, u32);
1032 
1033 /*!
1034   @brief 対応する C++ 関数 @ref nn::os::Thread::Start を参照してください。
1035 */
1036 NN_EXTERN_C void nnosThreadInitializeAndStart(nnosThread* this_, void (*f)(uptr), uptr param, uptr stackBottom, s32 priority, s32 coreNo);
1037 
1038 /*!
1039   @brief 対応する C++ 関数 @ref nn::os::Thread::TryStart を参照してください。
1040 */
1041 NN_EXTERN_C bool nnosThreadTryInitializeAndStart(nnosThread* this_, void (*f)(uptr), uptr param, uptr stackBottom, s32 priority, s32 coreNo);
1042 
1043 /*!
1044   @brief 対応する C++ 関数 @ref nn::os::Thread::Finalize を参照してください。
1045 */
1046 NN_EXTERN_C void nnosThreadFinalize(nnosThread* this_);
1047 
1048 /*!
1049   @brief 対応する C++ 関数 @ref nn::os::Thread::Join を参照してください。
1050 */
1051 NN_EXTERN_C void nnosThreadJoin(nnosThread* this_);
1052 
1053 /*!
1054   @brief 対応する C++ 関数 @ref nn::os::Thread::Sleep を参照してください。
1055 */
1056 NN_EXTERN_C void nnosThreadSleep(s64 nanoSeconds);
1057 
1058 /*!
1059   @brief 対応する C++ 関数 @ref nn::os::Thread::Yield を参照してください。
1060 */
1061 NN_EXTERN_C void nnosThreadYield(void);
1062 
1063 /*!
1064   @brief 対応する C++ 関数 @ref nn::os::Thread::GetCurrentId を参照してください。
1065 */
1066 NN_EXTERN_C bit32 nnosThreadGetCurrentId(void);
1067 
1068 /*!
1069   @brief 対応する C++ 関数 @ref nn::os::Thread::GetPriority を参照してください。
1070 */
1071 NN_EXTERN_C s32 nnosThreadGetPriority(const nnosThread* this_);
1072 
1073 /*!
1074   @brief 対応する C++ 関数 @ref nn::os::Thread::GetCurrentPriority を参照してください。
1075 */
1076 NN_EXTERN_C s32 nnosThreadGetCurrentPriority(void);
1077 
1078 /*!
1079   @brief 対応する C++ 関数 @ref nn::os::Thread::ChangePriority を参照してください。
1080 */
1081 NN_EXTERN_C void nnosThreadChangePriority(nnosThread* this_, s32 priority);
1082 
1083 /*!
1084   @brief 対応する C++ 関数 @ref nn::os::Thread::ChangeCurrentPriority を参照してください。
1085 */
1086 NN_EXTERN_C void nnosThreadChangeCurrentPriority(s32 priority);
1087 
1088     // スレッド Affinity の設定・取得
1089 
1090 /*!
1091   @brief 対応する C++ 関数 @ref nn::os::Thread::GetAffinityMask を参照してください。
1092 */
1093 NN_EXTERN_C void nnosThreadGetAffinityMask(const nnosThread* this_, bit8* pAffinityMask, s32 numProcessor);
1094 
1095 /*!
1096   @brief 対応する C++ 関数 @ref nn::os::Thread::GetCurrentAffinityMask を参照してください。
1097 */
1098 NN_EXTERN_C void nnosThreadGetCurrentAffinityMask(bit8* pAffinityMask, s32 numProcessor);
1099 
1100 /*!
1101   @brief 対応する C++ 関数 @ref nn::os::Thread::GetDefaultAffinityMask を参照してください。
1102 */
1103 NN_EXTERN_C void nnosThreadGetDefaultAffinityMask(bit8* pAffinityMask, s32 numProcessor);
1104 
1105 /*!
1106   @brief 対応する C++ 関数 @ref nn::os::Thread::ChangeAffinityMask を参照してください。
1107 */
1108 NN_EXTERN_C void nnosThreadChangeAffinityMask(nnosThread* this_, const bit8* pAffinityMask, s32 numProcessor);
1109 
1110 /*!
1111   @brief 対応する C++ 関数 @ref nn::os::Thread::ChangeCurrentAffinityMask を参照してください。
1112 */
1113 NN_EXTERN_C void nnosThreadChangeCurrentAffinityMask(const bit8* pAffinityMask, s32 numProcessor);
1114 
1115 /*!
1116   @brief 対応する C++ 関数 @ref nn::os::Thread::SetDefaultAffinityMask を参照してください。
1117 */
1118 NN_EXTERN_C void nnosThreadSetDefaultAffinityMask(const bit8* pAffinityMask, s32 numProcessor);
1119 
1120     // IdealProcessor の取得・設定
1121 
1122 /*!
1123   @brief 対応する C++ 関数 @ref nn::os::Thread::GetIdealProcessor を参照してください。
1124 */
1125 NN_EXTERN_C s32 nnosThreadGetIdealProcessor(const nnosThread* this_);
1126 
1127 /*!
1128   @brief 対応する C++ 関数 @ref nn::os::Thread::GetCurrentIdealProcessor を参照してください。
1129 */
1130 NN_EXTERN_C s32 nnosThreadGetCurrentIdealProcessor(void);
1131 
1132 /*!
1133   @brief 対応する C++ 関数 @ref nn::os::Thread::GetDefaultIdealProcessor を参照してください。
1134 */
1135 NN_EXTERN_C s32 nnosThreadGetDefaultIdealProcessor(void);
1136 
1137 /*!
1138   @brief 対応する C++ 関数 @ref nn::os::Thread::ChangeIdealProcessor を参照してください。
1139 */
1140 NN_EXTERN_C void nnosThreadChangeIdealProcessor(nnosThread* this_, s32 coreNo);
1141 
1142 /*!
1143   @brief 対応する C++ 関数 @ref nn::os::Thread::ChangeCurrentIdealProcessor を参照してください。
1144 */
1145 NN_EXTERN_C void nnosThreadChangeCurrentIdealProcessor(s32 coreNo);
1146 
1147 /*!
1148   @brief 対応する C++ 関数 @ref nn::os::Thread::SetDefaultIdealProcessor を参照してください。
1149 */
1150 NN_EXTERN_C void nnosThreadSetDefaultIdealProcessor(s32 coreNo);
1151 
1152     // カレントスレッドの動作しているプロセッサ番号の取得
1153 
1154 /*!
1155   @brief 対応する C++ 関数 @ref nn::os::Thread::GetCurrentProcessorNumber を参照してください。
1156 */
1157 NN_EXTERN_C s32 nnosThreadGetCurrentProcessorNumber(void);
1158 
1159 /*!
1160   @brief 対応する C++ 関数 @ref nn::os::Thread::GetID を参照してください。
1161 */
1162 NN_EXTERN_C bit32 nnosThreadGetId(nnosThread* this_);
1163 
1164 /*!
1165   @brief 対応する C++ 関数 @ref nn::os::Thread::IsAlive を参照してください。
1166 */
1167 NN_EXTERN_C bool nnosThreadIsAlive(nnosThread* this_);
1168 
1169 /*!
1170   @brief 対応する C++ 関数 @ref nn::os::Thread::GetMainThread を参照してください。
1171 */
1172 NN_EXTERN_C nnosThread* nnosThreadGetMainThread(void);
1173 
1174 /*!
1175   @}
1176   @}
1177 */
1178 
1179 /* NN_OS_THREAD_H_ */
1180 #endif
1181 
1182