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), ¶m, 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), ¶m, 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), ¶m, 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), ¶m, 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), ¶m, 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