1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     os_Thread.h
4   Copyright (C)2009 Nintendo Co., Ltd.  All rights reserved.
5   These coded instructions, statements, and computer programs contain
6   proprietary information of Nintendo of America Inc. and/or Nintendo
7   Company Ltd., and are protected by Federal copyright law. They may
8   not be disclosed to third parties or copied or duplicated in any form,
9   in whole or in part, without the prior written consent of Nintendo.
10   $Rev: 36485 $
11  *---------------------------------------------------------------------------
12 
13 
14 */
15 
16 /* Please see man pages for details
17 
18 
19 
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 
38 
39 */
40 #define NN_OS_CORE_NO_ALL                           (-1)
41 
42 /*
43 
44 
45 */
46 #define NN_OS_CORE_NO_USE_PROCESS_VALUE             (-2)
47 
48 #define NN_OS_THREAD_PRIORITY_RANGE_SIZE            32
49 
50 /*
51 
52 
53 */
54 #define NN_OS_LOWEST_THREAD_PRIORITY                (NN_OS_THREAD_PRIORITY_RANGE_SIZE - 1)
55 
56 /*
57 
58 
59 */
60 #define NN_OS_HIGHEST_THREAD_PRIORITY               0
61 
62 /*
63 
64 
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     void InitializeThreadEnvrionment();
80 }
81 
82 /*
83 
84 */
85 const s32 LOWEST_THREAD_PRIORITY = NN_OS_LOWEST_THREAD_PRIORITY;
86 
87 /*
88 
89 */
90 const s32 HIGHEST_THREAD_PRIORITY = NN_OS_HIGHEST_THREAD_PRIORITY;
91 
92 /*
93 
94 */
95 const s32 DEFAULT_THREAD_PRIORITY = NN_OS_DEFAULT_THREAD_PRIORITY;
96 
97 /*
98 
99 */
100 const s32 CORE_NO_ALL = NN_OS_CORE_NO_ALL;
101 
102 /*
103 
104 */
105 const s32 CORE_NO_USE_PROCESS_VALUE = NN_OS_CORE_NO_USE_PROCESS_VALUE;
106 
107 const s32 THREAD_PRIORITY_RANGE_SIZE = NN_OS_THREAD_PRIORITY_RANGE_SIZE;
108 
109 /*
110 
111 */
112 
113 /* Please see man pages for details
114 
115 
116 
117 
118 
119 
120 
121 
122 
123 
124 
125 
126 
127 
128 
129 
130 
131 
132 
133 
134 
135 
136 
137 
138 
139 
140 
141 
142 
143 
144 
145 
146 
147 
148 
149 
150 
151 
152 
153 
154 
155 
156 
157 
158 
159 
160 
161 
162 
163 
164 
165 
166 
167 
168 
169 
170 */
171 
172 class Thread : public WaitObject
173 {
174 public:
175     class AutoStackManager
176     {
177     public:
178         virtual void* Construct(size_t stackSize) = 0;
179         virtual void Destruct(void* pStackBottom, bool isError) = 0;
180     };
181 
182 public:
183 
184     /* Please see man pages for details
185 
186 
187 
188     */
Thread()189     Thread() : m_CanFinalize(true) {}
190 
191     /* Please see man pages for details
192 
193 
194 
195 
196     */
197     ~Thread();
198 
199     /* Please see man pages for details
200 
201 
202 
203 
204 
205 
206 
207 
208 
209 
210 
211 
212 
213 
214 
215 */
216     template <typename Stack>
217     void Start(void (*f)(), Stack& stack, s32 priority = DEFAULT_THREAD_PRIORITY, s32 coreNo = CORE_NO_USE_PROCESS_VALUE);
218 
219     /* Please see man pages for details
220 
221 
222 
223 
224 
225 
226 
227 
228 
229 
230 
231 
232 
233 
234 
235 
236 
237 
238 */
239     template <typename T, typename U, typename Stack>
240     void Start(void (*f)(T), U param, Stack& stack, s32 priority = DEFAULT_THREAD_PRIORITY, s32 coreNo = CORE_NO_USE_PROCESS_VALUE);
241     template <typename T, typename Stack>
242     void Start(void (*f)(const T*), const T& param, Stack& stack, s32 priority = DEFAULT_THREAD_PRIORITY, s32 coreNo = CORE_NO_USE_PROCESS_VALUE);
243     template <typename T, typename Stack>
244     void Start(void (*f)(const T&), const T& param, Stack& stack, s32 priority = DEFAULT_THREAD_PRIORITY, s32 coreNo = CORE_NO_USE_PROCESS_VALUE);
245 
246     /* Please see man pages for details
247 
248 
249 
250 
251 
252 
253 
254 
255 
256 
257 
258 
259 
260 
261 
262     */
263     template <typename Stack>
264     nn::Result TryStart(void (*f)(), Stack& stack, s32 priority = DEFAULT_THREAD_PRIORITY, s32 coreNo = CORE_NO_USE_PROCESS_VALUE);
265 
266     /* Please see man pages for details
267 
268 
269 
270 
271 
272 
273 
274 
275 
276 
277 
278 
279 
280 
281 
282 
283 
284 
285     */
286     template <typename T, typename U, typename Stack>
287     nn::Result TryStart(void (*f)(T), U param, Stack& stack, s32 priority = DEFAULT_THREAD_PRIORITY, s32 coreNo = CORE_NO_USE_PROCESS_VALUE);
288 
289     /* Please see man pages for details
290 
291 
292 
293 
294 
295 
296 
297 
298 
299 
300 
301 
302 
303     */
304     void StartUsingAutoStack(void (*f)(), size_t stackSize, s32 priority = DEFAULT_THREAD_PRIORITY, s32 coreNo = CORE_NO_USE_PROCESS_VALUE);
305 
306     /* Please see man pages for details
307 
308 
309 
310 
311 
312 
313 
314 
315 
316 
317 
318 
319 
320 
321 
322 
323 
324     */
325     template <typename T, typename U>
326     void StartUsingAutoStack(void (*f)(T), U param, size_t stackSize, s32 priority = DEFAULT_THREAD_PRIORITY, s32 coreNo = CORE_NO_USE_PROCESS_VALUE);
327 
328     /* Please see man pages for details
329 
330 
331 
332 
333 
334 
335 
336 
337 
338 
339 
340 
341 
342 
343 
344 
345 */
346     nn::Result TryStartUsingAutoStack(void (*f)(), size_t stackSize, s32 priority = DEFAULT_THREAD_PRIORITY, s32 coreNo = CORE_NO_USE_PROCESS_VALUE);
347 
348     /* Please see man pages for details
349 
350 
351 
352 
353 
354 
355 
356 
357 
358 
359 
360 
361 
362 
363 
364 
365 
366 
367 
368 
369 
370 */
371     template <typename T, typename U>
372     nn::Result TryStartUsingAutoStack(void (*f)(T), U param, size_t stackSize, s32 priority = DEFAULT_THREAD_PRIORITY, s32 coreNo = CORE_NO_USE_PROCESS_VALUE);
373 
374     /* Please see man pages for details
375 
376 
377 
378 
379 
380 
381 
382 */
383     void Finalize();
384 
385     /* Please see man pages for details
386 
387 
388 
389 
390 
391 
392 
393 
394     */
395     void Join();
396 
397     /* Please see man pages for details
398 
399 
400 
401 
402 
403 
404 
405 
406     */
407     void Detach();
408 
409     /* Please see man pages for details
410 
411 
412 
413     */
414     bool IsAlive() const;
415 
416     /* Please see man pages for details
417 
418 
419 
420 
421 
422     */
423     static void Sleep(nn::fnd::TimeSpan span);
424 
425     /* Please see man pages for details
426 
427 
428 
429 
430 
431 
432 
433 
434 
435 
436 
437 
438 
439 
440     */
441     static void Yield();
442 
443     // Get and set the thread state
444     // Non-static member functions affect instances.
445     // Static member functions that include "Current" in their name operate on the current thread.
446     // Static member functions that include "Default" in their name operate on the default values of the attributes of the thread being created when "coreNo = CORE_NO_USE_PROCESS_VALUE" in CreateThread.
447     //
448 
449     // Get context
450     //   TODO: Not yet implemented
451     // void GetContext(nn::os::ThreadContext* pContext) const;
452     // static void GetCurrentContext(nn::os::ThreadContext* pContext);
453 
454     /* Please see man pages for details
455 
456 
457 
458     */
459     bit32 GetId() const;
460 
461     /* Please see man pages for details
462 
463 
464 
465     */
466     static bit32 GetCurrentId();
467 
468     /* Please see man pages for details
469 
470 
471 
472     */
473     s32 GetPriority() const;
474 
475     /* Please see man pages for details
476 
477 
478 
479     */
480     static s32 GetCurrentPriority();
481 
482     /* Please see man pages for details
483 
484 
485 
486 
487 
488     */
489     void ChangePriority(s32 priority);
490 
491     /* Please see man pages for details
492 
493 
494 
495 
496 
497     */
498     static void ChangeCurrentPriority(s32 priority);
499 
500     // Sets and gets thread Affinity
501     //   Use structure or class to wrap AffinityMask?
502     /* Please see man pages for details
503 
504 
505 
506 
507 
508 
509 
510 
511     */
512     void GetAffinityMask(bit8* pAffinityMask, s32 numProcessor) const;
513 
514     /* Please see man pages for details
515 
516 
517 
518 
519 
520 
521 
522 
523     */
524     static void GetCurrentAffinityMask(bit8* pAffinityMask, s32 numProcessor);
525 
526     /* Please see man pages for details
527 
528 
529 
530 
531 
532 
533 
534 
535     */
536     static void GetDefaultAffinityMask(bit8* pAffinityMask, s32 numProcessor);
537 
538     /* Please see man pages for details
539 
540 
541 
542 
543 
544 
545 
546 
547     */
548     void ChangeAffinityMask(const bit8* pAffinityMask, s32 numProcessor);
549 
550     /* Please see man pages for details
551 
552 
553 
554 
555 
556 
557 
558 
559     */
560     static void ChangeCurrentAffinityMask(const bit8* pAffinityMask, s32 numProcessor);
561 
562     /* Please see man pages for details
563 
564 
565 
566 
567 
568 
569 
570 
571     */
572     static void SetDefaultAffinityMask(const bit8* pAffinityMask, s32 numProcessor);
573 
574     // Sets and gets IdealProcessor
575     /* Please see man pages for details
576 
577 
578 
579 
580 
581     */
582     s32 GetIdealProcessor() const;
583 
584     /* Please see man pages for details
585 
586 
587 
588 
589 
590     */
591     static s32 GetCurrentIdealProcessor();
592 
593     /* Please see man pages for details
594 
595 
596 
597 
598 
599     */
600     static s32 GetDefaultIdealProcessor();
601 
602     /* Please see man pages for details
603 
604 
605 
606 
607 
608 
609 
610     */
611     void ChangeIdealProcessor(s32 coreNo);
612 
613     /* Please see man pages for details
614 
615 
616 
617 
618 
619 
620 
621     */
622     static void ChangeCurrentIdealProcessor(s32 coreNo);
623 
624     /* Please see man pages for details
625 
626 
627 
628 
629 
630 
631 
632     */
633     static void SetDefaultIdealProcessor(s32 coreNo);
634 
635     /* Please see man pages for details
636 
637 
638 
639 
640 
641     */
642     static s32 GetCurrentProcessorNumber();
643 
644     /* Please see man pages for details
645 
646 
647     */
GetMainThread()648     static Thread& GetMainThread() { return s_MainThread; }
649 
650     static void SetAutoStackManager(AutoStackManager* pManager);
651 
652 
653 private:
654     struct InitializeAsCurrentTag {};
655     struct TypeInfo;
656     struct FunctionInfo;
657 
658 private:
659     bool        m_CanFinalize;
660     bool        m_UsingAutoStack;
661     NN_PADDING2;
662 
663     static Thread               s_MainThread;
664     static AutoStackManager*    s_pAutoStackManager;
665 
666 private:
667     Thread(const InitializeAsCurrentTag&);
668     void FinalizeImpl();
669 
670     Result TryInitializeAndStartImpl(const TypeInfo& typeInfo, ThreadFunc f, const void* p, uptr stackBottom, s32 priority, s32 coreNo, bool isAutoStack);
671     Result TryInitializeAndStartImplUsingAutoStack(const TypeInfo& typeInfo, ThreadFunc f, const void* p, size_t stackSize, s32 priority, s32 coreNo);
672 
673 private:
674     static void OnThreadStart();
675     static void OnThreadExit();
676 
677     static void ThreadStart(uptr);
678     static void ThreadStartUsingAutoStack(uptr);
679     static void NoParameterFunc(void (*)());
680     static void SleepImpl(nn::fnd::TimeSpan span);
681 
682     static void CallDestructorAndExit(void* pStackBottom);
683 };
684 
685 /* Please see man pages for details
686 
687 
688 
689 
690 
691 
692 */
693 template <size_t Size>
694 class StackBuffer
695 {
696 private:
697     typename nn::util::aligned_storage<Size, 8>::type m_Buffer;
698 public:
699 
700     /* Please see man pages for details
701 
702 
703 
704     */
GetStackBottom()705     uptr GetStackBottom() const { return reinterpret_cast<uptr>(this + 1); }
706 
707     void MarkCanary(bit32 value = 0xDEADBEEF) { reinterpret_cast<bit32*>(this)[0] = value; }
708     bool CheckCanary(bit32 value = 0xDEADBEEF) const { return reinterpret_cast<const bit32*>(this)[0] == value; }
709 };
710 
711 }}
712 
713 // In-line implementation
714 
715 #ifdef NN_SYSTEM_PROCESS
716 
717 #include <new>
718 
719 #include <nn/dbg/dbg_Logger.h>
720 
721 namespace nn { namespace os {
722 
723 struct Thread::TypeInfo
724 {
725 private:
726 
727     template <typename T, typename U>
CopyTypeInfo728     static void Copy(const void* src, void* dst)
729     {
730         new (dst) T(*reinterpret_cast<const U*>(src));
731     }
732     template <typename T>
CopyTypeInfo733     static void Copy(const void* src, void* dst)
734     {
735         new (dst) T(*reinterpret_cast<const T*>(src));
736     }
737 
738     template <typename T>
DestroyTypeInfo739     static void Destroy(void* p)
740     {
741         reinterpret_cast<T*>(p)->~T();
742     }
743 
744     template <typename T>
InvokeTypeInfo745     static void Invoke(ThreadFunc f, const void* p)
746     {
747         (*reinterpret_cast<void (*)(T)>(f))(*reinterpret_cast<const T*>(p));
748     }
749     template <typename T>
Invoke2TypeInfo750     static void Invoke2(ThreadFunc f, const void* p)
751     {
752         (*reinterpret_cast<void (*)(const T*)>(f))(reinterpret_cast<const T*>(p));
753     }
754 
755 public:
756 
757     size_t size;
758     void (*copy)(const void* src, void* dst);
759     void (*destroy)(void* p);
760     void (*invoke)(ThreadFunc f, const void* p);
761 
762     template <typename T, typename U>
763     void SetData(typename nn::util::enable_if<nn::util::is_convertible<U, T>::value>::type* = 0)
764     {
765         this->size = sizeof(T);
766         this->copy = &(Copy<T, U>);
767         this->destroy = &(Destroy<T>);
768         this->invoke = &(Invoke<T>);
769     }
770     template <typename T>
SetDataTypeInfo771     void SetData()
772     {
773         this->size = sizeof(T);
774         this->copy = &(Copy<T>);
775         this->destroy = &(Destroy<T>);
776         this->invoke = &(Invoke2<T>);
777     }
778 
779 };
780 
781 template <typename T, typename U, typename Stack>
Start(void (* f)(T),U param,Stack & stack,s32 priority,s32 coreNo)782 inline void Thread::Start(void (*f)(T), U param, Stack& stack, s32 priority, s32 coreNo)
783 {
784     TypeInfo info;
785     info.SetData<T, U>();
786     NN_ERR_THROW_FATAL(TryInitializeAndStartImpl(info, reinterpret_cast<ThreadFunc>(f), &param, stack.GetStackBottom(), priority, coreNo, false));
787 }
788 
789 template <typename T, typename Stack>
Start(void (* f)(const T *),const T & param,Stack & stack,s32 priority,s32 coreNo)790 inline void Thread::Start(void (*f)(const T*), const T& param, Stack& stack, s32 priority, s32 coreNo)
791 {
792     TypeInfo info;
793     info.SetData<T>();
794     NN_ERR_THROW_FATAL(TryInitializeAndStartImpl(info, reinterpret_cast<ThreadFunc>(f), &param, stack.GetStackBottom(), priority, coreNo, false));
795 }
796 
797 template <typename Stack>
Start(void (* f)(),Stack & stack,s32 priority,s32 coreNo)798 inline void Thread::Start(void (*f)(), Stack& stack, s32 priority, s32 coreNo)
799 {
800     Start(NoParameterFunc, f, stack, priority, coreNo);
801 }
802 
803 template <typename T, typename U, typename Stack>
TryStart(void (* f)(T),U param,Stack & stack,s32 priority,s32 coreNo)804 inline nn::Result Thread::TryStart(void (*f)(T), U param, Stack& stack, s32 priority, s32 coreNo)
805 {
806     TypeInfo info;
807     info.SetData<T, U>();
808     Result result = TryInitializeAndStartImpl(info, reinterpret_cast<ThreadFunc>(f), &param, stack.GetStackBottom(), priority, coreNo, false);
809     if (result.GetSummary() == Result::SUMMARY_OUT_OF_RESOURCE)
810     {
811         return result;
812     }
813     NN_ERR_THROW_FATAL(result);
814     return result;
815 }
816 
817 template <typename Stack>
TryStart(void (* f)(),Stack & stack,s32 priority,s32 coreNo)818 inline nn::Result Thread::TryStart(void (*f)(), Stack& stack, s32 priority, s32 coreNo)
819 {
820     return TryStart(NoParameterFunc, f, stack, priority, coreNo);
821 }
822 
823 template <typename T, typename U>
StartUsingAutoStack(void (* f)(T),U param,size_t stackSize,s32 priority,s32 coreNo)824 inline void Thread::StartUsingAutoStack(void (*f)(T), U param, size_t stackSize, s32 priority, s32 coreNo)
825 {
826     TypeInfo info;
827     info.SetData<T, U>();
828     NN_ERR_THROW_FATAL(TryInitializeAndStartImplUsingAutoStack(info, reinterpret_cast<ThreadFunc>(f), &param, stackSize, priority, coreNo));
829 }
830 
StartUsingAutoStack(void (* f)(),size_t stackSize,s32 priority,s32 coreNo)831 inline void Thread::StartUsingAutoStack(void (*f)(), size_t stackSize, s32 priority, s32 coreNo)
832 {
833     StartUsingAutoStack(NoParameterFunc, f, stackSize, priority, coreNo);
834 }
835 
836 template <typename T, typename U>
TryStartUsingAutoStack(void (* f)(T),U param,size_t stackSize,s32 priority,s32 coreNo)837 inline nn::Result Thread::TryStartUsingAutoStack(void (*f)(T), U param, size_t stackSize, s32 priority, s32 coreNo)
838 {
839     TypeInfo info;
840     info.SetData<T, U>();
841     Result result = TryInitializeAndStartImplUsingAutoStack(info, reinterpret_cast<ThreadFunc>(f), &param, stackSize, priority, coreNo);
842     if (result.GetSummary() == Result::SUMMARY_OUT_OF_RESOURCE)
843     {
844         return result;
845     }
846     NN_ERR_THROW_FATAL(result);
847     return result;
848 }
849 
TryStartUsingAutoStack(void (* f)(),size_t stackSize,s32 priority,s32 coreNo)850 inline nn::Result Thread::TryStartUsingAutoStack(void (*f)(), size_t stackSize, s32 priority, s32 coreNo)
851 {
852     return TryStartUsingAutoStack(NoParameterFunc, f, stackSize, priority, coreNo);
853 }
854 
FinalizeImpl()855 inline void Thread::FinalizeImpl()
856 {
857     if (!m_CanFinalize)
858     {
859         NN_TPANIC_("Thread is not Joined or Detached either.");
860     }
861 }
862 
Finalize()863 inline void Thread::Finalize()
864 {
865     FinalizeImpl();
866     this->WaitObject::Finalize();
867 }
868 
~Thread()869 inline Thread::~Thread()
870 {
871     FinalizeImpl();
872 }
873 
Join()874 inline void Thread::Join()
875 {
876     this->WaitOne();
877     this->m_CanFinalize = true;
878 }
879 
Detach()880 inline void Thread::Detach()
881 {
882     NN_TASSERT_(m_UsingAutoStack);
883     this->m_CanFinalize = true;
884     Finalize();
885 }
886 
IsAlive()887 inline bool Thread::IsAlive() const
888 {
889     if (IsValid())
890     {
891         return !const_cast<Thread*>(this)->WaitOne(0);
892     }
893     else
894     {
895         return false;
896     }
897 }
898 
Sleep(nn::fnd::TimeSpan span)899 inline void Thread::Sleep(nn::fnd::TimeSpan span)
900 {
901     SleepImpl(span);
902 }
903 
Yield()904 inline void Thread::Yield()
905 {
906     nn::svc::SleepThread(0);
907 }
908 
GetId()909 inline bit32 Thread::GetId() const
910 {
911     bit32 ret;
912     NN_ERR_THROW_FATAL(nn::svc::GetThreadId(&ret, GetHandle()));
913     return ret;
914 }
915 
GetCurrentId()916 inline bit32 Thread::GetCurrentId()
917 {
918     bit32 ret;
919     NN_ERR_THROW_FATAL(nn::svc::GetThreadId(&ret, PSEUDO_HANDLE_CURRENT_THREAD));
920     return ret;
921 }
922 
GetPriority()923 inline s32 Thread::GetPriority() const
924 {
925     s32 ret;
926     NN_ERR_THROW_FATAL(nn::svc::GetThreadPriority(&ret, GetHandle()));
927     return os::detail::ConvertSvcToLibraryPriority(ret);
928 }
929 
GetCurrentPriority()930 inline s32 Thread::GetCurrentPriority()
931 {
932     s32 ret;
933     NN_ERR_THROW_FATAL(nn::svc::GetThreadPriority(&ret, PSEUDO_HANDLE_CURRENT_THREAD));
934     return os::detail::ConvertSvcToLibraryPriority(ret);
935 }
936 
ChangePriority(s32 priority)937 inline void Thread::ChangePriority(s32 priority)
938 {
939     NN_ERR_THROW_FATAL(nn::svc::SetThreadPriority(GetHandle(), os::detail::ConvertLibraryToSvcPriority(priority)));
940 }
941 
ChangeCurrentPriority(s32 priority)942 inline void Thread::ChangeCurrentPriority(s32 priority)
943 {
944     NN_ERR_THROW_FATAL(nn::svc::SetThreadPriority(PSEUDO_HANDLE_CURRENT_THREAD, os::detail::ConvertLibraryToSvcPriority(priority)));
945 }
946 
GetAffinityMask(bit8 * pAffinityMask,s32 numProcessor)947 inline void Thread::GetAffinityMask(bit8* pAffinityMask, s32 numProcessor) const
948 {
949     NN_ERR_THROW_FATAL(nn::svc::GetThreadAffinityMask(pAffinityMask, GetHandle(), numProcessor));
950 }
951 
GetCurrentAffinityMask(bit8 * pAffinityMask,s32 numProcessor)952 inline void Thread::GetCurrentAffinityMask(bit8* pAffinityMask, s32 numProcessor)
953 {
954     NN_ERR_THROW_FATAL(nn::svc::GetThreadAffinityMask(pAffinityMask, PSEUDO_HANDLE_CURRENT_THREAD, numProcessor));
955 }
956 
GetDefaultAffinityMask(bit8 * pAffinityMask,s32 numProcessor)957 inline void Thread::GetDefaultAffinityMask(bit8* pAffinityMask, s32 numProcessor)
958 {
959     NN_ERR_THROW_FATAL(nn::svc::GetProcessAffinityMask(pAffinityMask, PSEUDO_HANDLE_CURRENT_PROCESS, numProcessor));
960 }
961 
ChangeAffinityMask(const bit8 * pAffinityMask,s32 numProcessor)962 inline void Thread::ChangeAffinityMask(const bit8* pAffinityMask, s32 numProcessor)
963 {
964     NN_ERR_THROW_FATAL(nn::svc::SetThreadAffinityMask(GetHandle(), pAffinityMask, numProcessor));
965 }
966 
ChangeCurrentAffinityMask(const bit8 * pAffinityMask,s32 numProcessor)967 inline void Thread::ChangeCurrentAffinityMask(const bit8* pAffinityMask, s32 numProcessor)
968 {
969     NN_ERR_THROW_FATAL(nn::svc::SetThreadAffinityMask(PSEUDO_HANDLE_CURRENT_THREAD, pAffinityMask, numProcessor));
970 }
971 
SetDefaultAffinityMask(const bit8 * pAffinityMask,s32 numProcessor)972 inline void Thread::SetDefaultAffinityMask(const bit8* pAffinityMask, s32 numProcessor)
973 {
974     NN_ERR_THROW_FATAL(nn::svc::SetProcessAffinityMask(PSEUDO_HANDLE_CURRENT_PROCESS, pAffinityMask, numProcessor));
975 }
976 
GetIdealProcessor()977 inline s32 Thread::GetIdealProcessor() const
978 {
979     s32 ret;
980     NN_ERR_THROW_FATAL(nn::svc::GetThreadIdealProcessor(&ret, GetHandle()));
981     return ret;
982 }
983 
GetCurrentIdealProcessor()984 inline s32 Thread::GetCurrentIdealProcessor()
985 {
986     s32 ret;
987     NN_ERR_THROW_FATAL(nn::svc::GetThreadIdealProcessor(&ret, PSEUDO_HANDLE_CURRENT_THREAD));
988     return ret;
989 }
990 
GetDefaultIdealProcessor()991 inline s32 Thread::GetDefaultIdealProcessor()
992 {
993     s32 ret;
994     NN_ERR_THROW_FATAL(nn::svc::GetProcessIdealProcessor(&ret, PSEUDO_HANDLE_CURRENT_PROCESS));
995     return ret;
996 }
997 
ChangeIdealProcessor(s32 coreNo)998 inline void Thread::ChangeIdealProcessor(s32 coreNo)
999 {
1000     NN_ERR_THROW_FATAL(nn::svc::SetThreadIdealProcessor(GetHandle(), coreNo));
1001 }
1002 
ChangeCurrentIdealProcessor(s32 coreNo)1003 inline void Thread::ChangeCurrentIdealProcessor(s32 coreNo)
1004 {
1005     NN_ERR_THROW_FATAL(nn::svc::SetThreadIdealProcessor(PSEUDO_HANDLE_CURRENT_THREAD, coreNo));
1006 }
1007 
SetDefaultIdealProcessor(s32 coreNo)1008 inline void Thread::SetDefaultIdealProcessor(s32 coreNo)
1009 {
1010     NN_ERR_THROW_FATAL(nn::svc::SetProcessIdealProcessor(PSEUDO_HANDLE_CURRENT_PROCESS, coreNo));
1011 }
1012 
GetCurrentProcessorNumber()1013 inline s32 Thread::GetCurrentProcessorNumber()
1014 {
1015     return nn::svc::GetCurrentProcessorNumber();
1016 }
1017 
1018 
1019 /*
1020 
1021 */
1022 /*
1023 
1024 */
1025 
1026 }} // namespace nn::os
1027 
1028 #endif // NN_SYSTEM_PROCESS
1029 
1030 #endif // __cplusplus
1031 
1032 // C declarations follow
1033 
1034 #include <nn/util/detail/util_CLibImpl.h>
1035 
1036 
1037 /* Please see man pages for details
1038 
1039 
1040 
1041 
1042 
1043 
1044 
1045 
1046 */
1047 
1048 /* Please see man pages for details
1049 
1050 
1051 
1052 
1053 */
1054 NN_UTIL_DETAIL_CLIBIMPL_DEFINE_BUFFER_CLASS(nnosThread, nn::os::Thread, 8, u32);
1055 
1056 /* Please see man pages for details
1057 
1058 */
1059 NN_EXTERN_C void nnosThreadInitializeAndStart(nnosThread* this_, void (*f)(uptr), uptr param, uptr stackBottom, s32 priority, s32 coreNo);
1060 
1061 /* Please see man pages for details
1062 
1063 */
1064 NN_EXTERN_C bool nnosThreadTryInitializeAndStart(nnosThread* this_, void (*f)(uptr), uptr param, uptr stackBottom, s32 priority, s32 coreNo);
1065 
1066 /* Please see man pages for details
1067 
1068 */
1069 NN_EXTERN_C void nnosThreadFinalize(nnosThread* this_);
1070 
1071 /* Please see man pages for details
1072 
1073 */
1074 NN_EXTERN_C void nnosThreadJoin(nnosThread* this_);
1075 
1076 /* Please see man pages for details
1077 
1078 */
1079 NN_EXTERN_C void nnosThreadSleep(s64 nanoSeconds);
1080 
1081 /* Please see man pages for details
1082 
1083 */
1084 NN_EXTERN_C void nnosThreadYield(void);
1085 
1086 /* Please see man pages for details
1087 
1088 */
1089 NN_EXTERN_C bit32 nnosThreadGetCurrentId(void);
1090 
1091 /* Please see man pages for details
1092 
1093 */
1094 NN_EXTERN_C s32 nnosThreadGetPriority(const nnosThread* this_);
1095 
1096 /* Please see man pages for details
1097 
1098 */
1099 NN_EXTERN_C s32 nnosThreadGetCurrentPriority(void);
1100 
1101 /* Please see man pages for details
1102 
1103 */
1104 NN_EXTERN_C void nnosThreadChangePriority(nnosThread* this_, s32 priority);
1105 
1106 /* Please see man pages for details
1107 
1108 */
1109 NN_EXTERN_C void nnosThreadChangeCurrentPriority(s32 priority);
1110 
1111     // Sets and gets thread Affinity
1112 
1113 /* Please see man pages for details
1114 
1115 */
1116 NN_EXTERN_C void nnosThreadGetAffinityMask(const nnosThread* this_, bit8* pAffinityMask, s32 numProcessor);
1117 
1118 /* Please see man pages for details
1119 
1120 */
1121 NN_EXTERN_C void nnosThreadGetCurrentAffinityMask(bit8* pAffinityMask, s32 numProcessor);
1122 
1123 /* Please see man pages for details
1124 
1125 */
1126 NN_EXTERN_C void nnosThreadGetDefaultAffinityMask(bit8* pAffinityMask, s32 numProcessor);
1127 
1128 /* Please see man pages for details
1129 
1130 */
1131 NN_EXTERN_C void nnosThreadChangeAffinityMask(nnosThread* this_, const bit8* pAffinityMask, s32 numProcessor);
1132 
1133 /* Please see man pages for details
1134 
1135 */
1136 NN_EXTERN_C void nnosThreadChangeCurrentAffinityMask(const bit8* pAffinityMask, s32 numProcessor);
1137 
1138 /* Please see man pages for details
1139 
1140 */
1141 NN_EXTERN_C void nnosThreadSetDefaultAffinityMask(const bit8* pAffinityMask, s32 numProcessor);
1142 
1143     // Sets and gets IdealProcessor
1144 
1145 /* Please see man pages for details
1146 
1147 */
1148 NN_EXTERN_C s32 nnosThreadGetIdealProcessor(const nnosThread* this_);
1149 
1150 /* Please see man pages for details
1151 
1152 */
1153 NN_EXTERN_C s32 nnosThreadGetCurrentIdealProcessor(void);
1154 
1155 /* Please see man pages for details
1156 
1157 */
1158 NN_EXTERN_C s32 nnosThreadGetDefaultIdealProcessor(void);
1159 
1160 /* Please see man pages for details
1161 
1162 */
1163 NN_EXTERN_C void nnosThreadChangeIdealProcessor(nnosThread* this_, s32 coreNo);
1164 
1165 /* Please see man pages for details
1166 
1167 */
1168 NN_EXTERN_C void nnosThreadChangeCurrentIdealProcessor(s32 coreNo);
1169 
1170 /* Please see man pages for details
1171 
1172 */
1173 NN_EXTERN_C void nnosThreadSetDefaultIdealProcessor(s32 coreNo);
1174 
1175     // Get the number of the processor that the current thread is running on
1176 
1177 /* Please see man pages for details
1178 
1179 */
1180 NN_EXTERN_C s32 nnosThreadGetCurrentProcessorNumber(void);
1181 
1182 /* Please see man pages for details
1183 
1184 */
1185 NN_EXTERN_C bit32 nnosThreadGetId(nnosThread* this_);
1186 
1187 /* Please see man pages for details
1188 
1189 */
1190 NN_EXTERN_C bool nnosThreadIsAlive(nnosThread* this_);
1191 
1192 /* Please see man pages for details
1193 
1194 */
1195 NN_EXTERN_C nnosThread* nnosThreadGetMainThread(void);
1196 
1197 /*
1198 
1199 
1200 */
1201 
1202 /* NN_OS_THREAD_H_ */
1203 #endif
1204 
1205