1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     os_ManagedThread.h
4 
5   Copyright (C)2009-2012 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: 50238 $
14  *---------------------------------------------------------------------------*/
15 
16 /* Please see man pages for details
17 
18 
19 
20 */
21 
22 #ifndef NN_OS_OS_MANAGEDTHREAD_H_
23 #define NN_OS_OS_MANAGEDTHREAD_H_
24 
25 #include <nn/types.h>
26 #include <nn/os/os_Thread.h>
27 #include <nn/os/os_ThreadLocalStorage.h>
28 #include <nn/util.h>
29 #include <nn/fnd/fnd_LinkedList.h>
30 
31 
32 #ifdef __cplusplus
33 
34 
35 namespace nn{ namespace os{
36 
37 
38 
39     //----------------------------------------------------------------------
40     //
41     //
42     //
43     //
44     //
45     //
46     //
47     //
48     //
49     //
50     //
51     //
52     //
53     //
54     //
55     //
56     //
57     //
58     //
59     //
60     //
61     //
62     //
63     //----------------------------------------------------------------------
64     class ManagedThread : public fnd::IntrusiveLinkedList<ManagedThread>::Item, public util::NonCopyable<ManagedThread>
65     {
66     private:
67         static const s32 PRIORITY_DEFAULT = DEFAULT_THREAD_PRIORITY;
68         static const s32 CORE_NO_DEFAULT  = CORE_NO_USE_PROCESS_VALUE;
69 
70         struct TypeInfo;
71         struct StartParam;
72 
73     public:
74         //----------------------------------------------------------------------
75         //
76         //
77         //
78         //
79         //
80         //
81         //----------------------------------------------------------------------
82         class EnumerateCallback
83         {
84         public:
85             //----------------------------------------------------------------------
86             //
87             //
88             //
89             //
90             //
91             //
92             //
93             //
94             //
95             //
96             //
97             //
98             //
99             //
100             //
101             //----------------------------------------------------------------------
102             virtual bool operator()(ManagedThread* p) = 0;
103         };
104 
105     public:
106 
107     //
108     //
109 
110         //----------------------------------------------------------------------
111         //
112         //
113         //
114         //
115         //
116         //----------------------------------------------------------------------
ManagedThread()117         ManagedThread() {}
118 
119         //----------------------------------------------------------------------
120         //
121         //
122         //
123         //
124         //
125         //
126         //----------------------------------------------------------------------
~ManagedThread()127         ~ManagedThread() { Finalize(); }
128 
129     //
130 
131     //
132     //
133 
134         //----------------------------------------------------------------------
135         //
136         //
137         //
138         //
139         //
140         //
141         //
142         //
143         //
144         //
145         //
146         //
147         //
148         //
149         //
150         //----------------------------------------------------------------------
151         template <typename T, typename U, typename Stack>
152         nn::Result TryInitialize              (void (*f)(T),  U param , Stack& stack,     s32 priority = PRIORITY_DEFAULT, s32 coreNo = CORE_NO_DEFAULT);
153         //----------------------------------------------------------------------
154         //
155         //
156         //
157         //
158         //
159         //
160         //
161         //
162         //
163         //
164         //
165         //
166         //
167         //
168         //----------------------------------------------------------------------
169         template <typename T, typename Stack>
170         nn::Result TryInitialize              (void (*f)(T*), const T& param, Stack& stack,     s32 priority = PRIORITY_DEFAULT, s32 coreNo = CORE_NO_DEFAULT);
171         //----------------------------------------------------------------------
172         //
173         //
174         //
175         //
176         //
177         //
178         //
179         //
180         //
181         //
182         //
183         //
184         //
185         //
186         //----------------------------------------------------------------------
187         template <typename T, typename Stack>
188         nn::Result TryInitialize              (void (*f)(const T*), const T& param, Stack& stack, s32 priority = PRIORITY_DEFAULT, s32 coreNo = CORE_NO_DEFAULT);
189         //----------------------------------------------------------------------
190         //
191         //
192         //
193         //
194         //
195         //
196         //
197         //
198         //
199         //
200         //
201         //
202         //----------------------------------------------------------------------
203         template <typename Stack>
204         nn::Result TryInitialize              (void (*f)(),             Stack& stack,     s32 priority = PRIORITY_DEFAULT, s32 coreNo = CORE_NO_DEFAULT);
205 
206         //----------------------------------------------------------------------
207         //
208         //
209         //
210         //
211         //
212         //
213         //
214         //
215         //
216         //
217         //
218         //
219         //
220         //----------------------------------------------------------------------
221         template <typename T, typename U, typename Stack>
222         void       Initialize                 (void (*f)(T),  U param,  Stack& stack,     s32 priority = PRIORITY_DEFAULT, s32 coreNo = CORE_NO_DEFAULT);
223         //----------------------------------------------------------------------
224         //
225         //
226         //
227         //
228         //
229         //
230         //
231         //
232         //
233         //
234         //
235         //
236         //----------------------------------------------------------------------
237         template <typename T, typename Stack>
238         void       Initialize                 (void (*f)(T*), const T& param, Stack& stack,     s32 priority = PRIORITY_DEFAULT, s32 coreNo = CORE_NO_DEFAULT);
239         //----------------------------------------------------------------------
240         //
241         //
242         //
243         //
244         //
245         //
246         //
247         //
248         //
249         //
250         //
251         //
252         //----------------------------------------------------------------------
253         template <typename T, typename Stack>
254         void       Initialize                 (void (*f)(const T*), const T& param, Stack& stack, s32 priority = PRIORITY_DEFAULT, s32 coreNo = CORE_NO_DEFAULT);
255         //----------------------------------------------------------------------
256         //
257         //
258         //
259         //
260         //
261         //
262         //
263         //
264         //
265         //
266         //----------------------------------------------------------------------
267         template <typename Stack>
268         void       Initialize                 (void (*f)(),             Stack& stack,     s32 priority = PRIORITY_DEFAULT, s32 coreNo = CORE_NO_DEFAULT);
269 
270         //----------------------------------------------------------------------
271         //
272         //
273         //
274         //
275         //
276         //
277         //
278         //
279         //
280         //
281         //
282         //
283         //
284         //
285         //----------------------------------------------------------------------
286         template <typename T, typename U>
287         nn::Result TryInitializeUsingAutoStack(void (*f)(T),  U param,  size_t stackSize, s32 priority = PRIORITY_DEFAULT, s32 coreNo = CORE_NO_DEFAULT);
288         //----------------------------------------------------------------------
289         //
290         //
291         //
292         //
293         //
294         //
295         //
296         //
297         //
298         //
299         //
300         //
301         //
302         //----------------------------------------------------------------------
303         template <typename T>
304         nn::Result TryInitializeUsingAutoStack(void (*f)(T*), const T& param, size_t stackSize, s32 priority = PRIORITY_DEFAULT, s32 coreNo = CORE_NO_DEFAULT);
305         //----------------------------------------------------------------------
306         //
307         //
308         //
309         //
310         //
311         //
312         //
313         //
314         //
315         //
316         //
317         //
318         //
319         //----------------------------------------------------------------------
320         template <typename T>
321         nn::Result TryInitializeUsingAutoStack(void (*f)(const T*), const T& param, size_t stackSize, s32 priority = PRIORITY_DEFAULT, s32 coreNo = CORE_NO_DEFAULT);
322         //----------------------------------------------------------------------
323         //
324         //
325         //
326         //
327         //
328         //
329         //
330         //
331         //
332         //
333         //----------------------------------------------------------------------
334         nn::Result TryInitializeUsingAutoStack(void (*f)(),             size_t stackSize, s32 priority = PRIORITY_DEFAULT, s32 coreNo = CORE_NO_DEFAULT);
335 
336         //----------------------------------------------------------------------
337         //
338         //
339         //
340         //
341         //
342         //
343         //
344         //
345         //
346         //
347         //
348         //
349         //----------------------------------------------------------------------
350         template <typename T, typename U>
351         void       InitializeUsingAutoStack   (void (*f)(T),  U param,  size_t stackSize, s32 priority = PRIORITY_DEFAULT, s32 coreNo = CORE_NO_DEFAULT);
352         //----------------------------------------------------------------------
353         //
354         //
355         //
356         //
357         //
358         //
359         //
360         //
361         //
362         //
363         //
364         //----------------------------------------------------------------------
365         template <typename T>
366         void       InitializeUsingAutoStack   (void (*f)(T*), const T& param, size_t stackSize, s32 priority = PRIORITY_DEFAULT, s32 coreNo = CORE_NO_DEFAULT);
367         //----------------------------------------------------------------------
368         //
369         //
370         //
371         //
372         //
373         //
374         //
375         //
376         //
377         //
378         //
379         //----------------------------------------------------------------------
380         template <typename T>
381         void       InitializeUsingAutoStack   (void (*f)(const T*), const T& param, size_t stackSize, s32 priority = PRIORITY_DEFAULT, s32 coreNo = CORE_NO_DEFAULT);
382         //----------------------------------------------------------------------
383         //
384         //
385         //
386         //
387         //
388         //
389         //
390         //
391         //----------------------------------------------------------------------
392         void       InitializeUsingAutoStack   (void (*f)(),             size_t stackSize, s32 priority = PRIORITY_DEFAULT, s32 coreNo = CORE_NO_DEFAULT);
393 
394     //
395 
396     //
397     //
398 
399         //----------------------------------------------------------------------
400         //
401         //
402         //
403         //
404         //
405         //----------------------------------------------------------------------
406         void    Start();
407 
408     //
409 
410     //
411     //
412 
413         //----------------------------------------------------------------------
414         //
415         //
416         //
417         //
418         //
419         //
420         //
421         //
422         //
423         //----------------------------------------------------------------------
424         void Finalize();
425 
426         //----------------------------------------------------------------------
427         //
428         //
429         //
430         //
431         //----------------------------------------------------------------------
432         void Join();
433 
434         //----------------------------------------------------------------------
435         //
436         //
437         //
438         //
439         //
440         //
441         //
442         //
443         //
444         //
445         //
446         //
447         //
448         //
449         //
450         //----------------------------------------------------------------------
451         void Detach();
452 
453         //----------------------------------------------------------------------
454         //
455         //
456         //
457         //
458         //
459         //
460         //
461         //----------------------------------------------------------------------
IsAlive()462         bool IsAlive() const    { return m_Thread.IsAlive(); }
463 
464         //----------------------------------------------------------------------
465         //
466         //
467         //
468         //
469         //
470         //
471         //
472         //----------------------------------------------------------------------
IsValid()473         bool IsValid() const    { return m_Thread.IsValid(); }
474 
475     //
476 
477     //
478     //
479 
480         //----------------------------------------------------------------------
481         //
482         //
483         //
484         //
485         //
486         //
487         //----------------------------------------------------------------------
GetId()488         bit32 GetId() const                     { return m_Id; }
489 
490         //----------------------------------------------------------------------
491         //
492         //
493         //
494         //
495         //
496         //
497         //
498         //
499         //
500         //
501         //
502         //
503         //
504         //
505         //----------------------------------------------------------------------
GetCurrentId()506         static bit32 GetCurrentId()             { return ms_IdStorage.GetValue(); }
507 
508         //----------------------------------------------------------------------
509         //
510         //
511         //
512         //
513         //
514         //
515         //----------------------------------------------------------------------
GetPriority()516         s32 GetPriority() const                 { return m_Thread.GetPriority(); }
517 
518         //----------------------------------------------------------------------
519         //
520         //
521         //
522         //
523         //----------------------------------------------------------------------
ChangePriority(s32 priority)524         void ChangePriority(s32 priority)       { m_Thread.ChangePriority(priority); }
525 
526         //----------------------------------------------------------------------
527         //
528         //
529         //
530         //
531         //
532         //
533         //----------------------------------------------------------------------
GetIdealProcessor()534         s32 GetIdealProcessor() const           { return m_Thread.GetIdealProcessor(); }
535 
536     //
537 
538     //
539     //
540 
541         //----------------------------------------------------------------------
542         //
543         //
544         //
545         //
546         //
547         //
548         //
549         //----------------------------------------------------------------------
550         uptr    GetStackBufferBegin() const;
551 
552         //----------------------------------------------------------------------
553         //
554         //
555         //
556         //
557         //
558         //
559         //
560         //
561         //
562         //
563         //----------------------------------------------------------------------
564         uptr    GetStackBottom() const;
565 
566         //----------------------------------------------------------------------
567         //
568         //
569         //
570         //
571         //
572         //
573         //
574         //
575         //
576         //
577         //----------------------------------------------------------------------
578         uptr    GetStackBufferEnd() const;
579 
580         //----------------------------------------------------------------------
581         //
582         //
583         //
584         //
585         //
586         //
587         //
588         //
589         //----------------------------------------------------------------------
590         size_t  GetStackSize() const;
591 
592         //----------------------------------------------------------------------
593         //
594         //
595         //
596         //
597         //
598         //
599         //
600         //----------------------------------------------------------------------
601         size_t  GetStackBufferSize() const;
602 
603     //
604 
605     //
606     //
607 
608         //----------------------------------------------------------------------
609         //
610         //
611         //
612         //
613         //
614         //----------------------------------------------------------------------
615         const char8* GetName() const;
616 
617         //----------------------------------------------------------------------
618         //
619         //
620         //
621         //
622         //
623         //
624         //
625         //
626         //
627         //----------------------------------------------------------------------
628         void    SetName(const char8* pName);
629 
630     //
631 
632     //
633     //
634 
635         //----------------------------------------------------------------------
636         //
637         //
638         //
639         //
640         //
641         //
642         //
643         //
644         //
645         //
646         //
647         //
648         //----------------------------------------------------------------------
649         static ManagedThread* GetCurrentThread();
650 
651         //----------------------------------------------------------------------
652         //
653         //
654         //
655         //
656         //
657         //
658         //
659         //
660         //
661         //
662         //
663         //
664         //
665         //
666         //
667         //
668         //
669         //
670         //
671         //
672         //
673         //
674         //
675         //
676         //----------------------------------------------------------------------
677         static ManagedThread* FindByStackAddress(uptr address);
678 
679         //----------------------------------------------------------------------
680         //
681         //
682         //
683         //
684         //
685         //
686         //
687         //
688         //
689         //
690         //
691         //
692         //
693         //
694         //----------------------------------------------------------------------
695         static ManagedThread* FindById(bit32 id);
696 
697         //----------------------------------------------------------------------
698         //
699         //
700         //
701         //
702         //
703         //
704         //
705         //
706         //
707         //
708         //
709         //
710         //
711         //
712         //
713         //
714         //
715         //
716         //
717         //
718         //----------------------------------------------------------------------
719         static void Enumerate(EnumerateCallback* p);
720 
721         //----------------------------------------------------------------------
722         //
723         //
724         //
725         //
726         //
727         //
728         //----------------------------------------------------------------------
729         static s32  GetCurrentManagedCount();
730 
731         //----------------------------------------------------------------------
732         //
733         //
734         //
735         //
736         //
737         //
738         //
739         //
740         //----------------------------------------------------------------------
741         static void InitializeEnvironment();
742 
743         //----------------------------------------------------------------------
744         //
745         //
746         //
747         //
748         //
749         //
750         //----------------------------------------------------------------------
751         static bool IsEnabled();
752 
753     //
754 
755     private:
756         Result TryInitialize(const TypeInfo& typeInfo, ThreadFunc f, const void* p, uptr stackBottom, size_t stackSize, s32 priority, s32 coreNo);
757         Result TryInitializeUsingAutoStack(const TypeInfo& typeInfo, ThreadFunc f, const void* p, size_t stackSize, s32 priority, s32 coreNo);
758 
759         void InitializeAsMainThread();
760 
761         static void Register(ManagedThread* p);
762         static void Unregister(ManagedThread* p);
763 
764         static void SetCurrentThread(ManagedThread* p);
765         static void SetCurrentThreadId(bit32 id);
766 
767     private:
768         Result TryInitializeImpl(
769                 const TypeInfo& typeInfo,
770                 ThreadFunc      f,
771                 const void*     p,
772                 uptr            stackBottom,
773                 size_t          stackSize,
774                 s32             priority,
775                 s32             coreNo );
776         Result TryInitializeImpl(
777                 const TypeInfo& typeInfo,
778                 ThreadFunc      f,
779                 const void*     p,
780                 uptr            stackBottom,
781                 size_t          stackSize,
782                 s32             priority,
783                 s32             coreNo,
784                 bool            useAutoStack );
785         Result TryInitializeImplUsingAutoStack(const TypeInfo& typeInfo, ThreadFunc f, const void* p, size_t stackSize, s32 priority, s32 coreNo);
786         uptr SetupStackAndParam(StartParam* pParam, const TypeInfo& typeInfo, ThreadFunc f, const void* p, uptr stackBottom, size_t stackSize);
787 
788     private:
789         static void ThreadStart(StartParam* p);
790         static void ThreadStartUsingAutoStack(uptr);
791         static void NoParameterFunc(void (*)());
792 
793     private:
794         Thread          m_Thread;
795         uptr            m_StackBottom;
796         uptr            m_StackBufferEnd;
797         size_t          m_StackSize;
798         LightEvent*     m_pStartEvent;
799         const char8*    m_pName;
800         bit32           m_Id;
801 
802     private:
803         static ThreadLocalStorage   ms_ThreadStorage;
804         static ThreadLocalStorage   ms_IdStorage;
805     };
806 
807 
808 #ifdef NN_SYSTEM_PROCESS
809 
810     struct ManagedThread::TypeInfo
811     {
812     private:
813 
814         template <typename T, typename U>
CopyTypeInfo815         static void Copy(const void* src, void* dst)
816         {
817             new (dst) T(*reinterpret_cast<const U*>(src));
818         }
819         template <typename T>
CopyTypeInfo820         static void Copy(const void* src, void* dst)
821         {
822             new (dst) T(*reinterpret_cast<const T*>(src));
823         }
824 
825         template <typename T>
DestroyTypeInfo826         static void Destroy(void* p)
827         {
828             reinterpret_cast<T*>(p)->~T();
829         }
830 
831         template <typename T>
InvokeTypeInfo832         static void Invoke(ThreadFunc f, const void* p)
833         {
834             (*reinterpret_cast<void (*)(T)>(f))(*reinterpret_cast<const T*>(p));
835         }
836         template <typename T>
Invoke2TypeInfo837         static void Invoke2(ThreadFunc f, const void* p)
838         {
839             (*reinterpret_cast<void (*)(const T*)>(f))(reinterpret_cast<const T*>(p));
840         }
841 
842     public:
843 
844         size_t size;
845         void (*copy)(const void* src, void* dst);
846         void (*destroy)(void* p);
847         void (*invoke)(ThreadFunc f, const void* p);
848 
849         template <typename T, typename U>
850         TypeInfo(T* dummy1, U* dummy2, typename nn::util::enable_if<nn::util::is_convertible<U, T>::value>::type* = 0)
851         {
852             NN_UNUSED_VAR(dummy1);
853             NN_UNUSED_VAR(dummy2);
854             this->size = sizeof(T);
855             this->copy = &(Copy<T, U>);
856             this->destroy = &(Destroy<T>);
857             this->invoke = &(Invoke<T>);
858         }
859         template <typename T>
TypeInfoTypeInfo860         TypeInfo(T* dummy)
861         {
862             NN_UNUSED_VAR(dummy);
863             this->size = sizeof(T);
864             this->copy = &(Copy<T>);
865             this->destroy = &(Destroy<T>);
866             this->invoke = &(Invoke2<T>);
867         }
868     };
869 
870 
871 
872     template <typename T, typename U, typename Stack>
TryInitialize(void (* f)(T),U param,Stack & stack,s32 priority,s32 coreNo)873     inline nn::Result ManagedThread::TryInitialize(void (*f)(T), U param, Stack& stack, s32 priority, s32 coreNo)
874     {
875         return TryInitializeImpl(
876                             TypeInfo(reinterpret_cast<T*>(NULL), &param),
877                             reinterpret_cast<ThreadFunc>(f),
878                             &param,
879                             stack.GetStackBottom(),
880                             stack.GetStackSize(),
881                             priority,
882                             coreNo );
883     }
884     template <typename T, typename Stack>
TryInitialize(void (* f)(T *),const T & param,Stack & stack,s32 priority,s32 coreNo)885     inline nn::Result ManagedThread::TryInitialize(void (*f)(T*), const T& param, Stack& stack, s32 priority, s32 coreNo)
886     {
887         return TryInitializeImpl(
888                             TypeInfo(reinterpret_cast<T*>(NULL)),
889                             reinterpret_cast<ThreadFunc>(f),
890                             &param,
891                             stack.GetStackBottom(),
892                             stack.GetStackSize(),
893                             priority,
894                             coreNo );
895     }
896     template <typename T, typename Stack>
TryInitialize(void (* f)(const T *),const T & param,Stack & stack,s32 priority,s32 coreNo)897     inline nn::Result ManagedThread::TryInitialize(void (*f)(const T*), const T& param, Stack& stack, s32 priority, s32 coreNo)
898     {
899         return TryInitializeImpl(
900                             TypeInfo(reinterpret_cast<T*>(NULL)),
901                             reinterpret_cast<ThreadFunc>(f),
902                             &param,
903                             stack.GetStackBottom(),
904                             stack.GetStackSize(),
905                             priority,
906                             coreNo );
907     }
908     template <typename Stack>
TryInitialize(void (* f)(),Stack & stack,s32 priority,s32 coreNo)909     inline nn::Result ManagedThread::TryInitialize(void (*f)(), Stack& stack, s32 priority, s32 coreNo)
910     {
911         return TryInitialize(NoParameterFunc, f, stack, priority, coreNo);
912     }
913 
914     template <typename T, typename U, typename Stack>
Initialize(void (* f)(T),U param,Stack & stack,s32 priority,s32 coreNo)915     inline void ManagedThread::Initialize(void (*f)(T), U param, Stack& stack, s32 priority, s32 coreNo)
916     {
917         NN_OS_ERROR_IF_FAILED(
918             TryInitializeImpl(
919                 TypeInfo(reinterpret_cast<T*>(NULL), &param),
920                 reinterpret_cast<ThreadFunc>(f),
921                 &param,
922                 stack.GetStackBottom(),
923                 stack.GetStackSize(),
924                 priority,
925                 coreNo ) );
926     }
927     template <typename T, typename Stack>
Initialize(void (* f)(T *),const T & param,Stack & stack,s32 priority,s32 coreNo)928     inline void ManagedThread::Initialize(void (*f)(T*), const T& param, Stack& stack, s32 priority, s32 coreNo)
929     {
930         NN_OS_ERROR_IF_FAILED(
931             TryInitializeImpl(
932                 TypeInfo(reinterpret_cast<T*>(NULL)),
933                 reinterpret_cast<ThreadFunc>(f),
934                 &param,
935                 stack.GetStackBottom(),
936                 stack.GetStackSize(),
937                 priority,
938                 coreNo ) );
939     }
940     template <typename T, typename Stack>
Initialize(void (* f)(const T *),const T & param,Stack & stack,s32 priority,s32 coreNo)941     inline void ManagedThread::Initialize(void (*f)(const T*), const T& param, Stack& stack, s32 priority, s32 coreNo)
942     {
943         NN_OS_ERROR_IF_FAILED(
944             TryInitializeImpl(
945                 TypeInfo(reinterpret_cast<const T*>(NULL)),
946                 reinterpret_cast<ThreadFunc>(f),
947                 &param,
948                 stack.GetStackBottom(),
949                 stack.GetStackSize(),
950                 priority,
951                 coreNo ) );
952     }
953     template <typename Stack>
Initialize(void (* f)(),Stack & stack,s32 priority,s32 coreNo)954     inline void ManagedThread::Initialize(void (*f)(), Stack& stack, s32 priority, s32 coreNo)
955     {
956         Initialize(NoParameterFunc, f, stack, priority, coreNo);
957     }
958 
959     template <typename T, typename U>
TryInitializeUsingAutoStack(void (* f)(T),U param,size_t stackSize,s32 priority,s32 coreNo)960     inline nn::Result ManagedThread::TryInitializeUsingAutoStack(void (*f)(T), U param, size_t stackSize, s32 priority, s32 coreNo)
961     {
962         return TryInitializeImplUsingAutoStack(
963                             TypeInfo(reinterpret_cast<T*>(NULL), &param),
964                             reinterpret_cast<ThreadFunc>(f),
965                             &param,
966                             stackSize,
967                             priority,
968                             coreNo );
969     }
970     template <typename T>
TryInitializeUsingAutoStack(void (* f)(T *),const T & param,size_t stackSize,s32 priority,s32 coreNo)971     inline nn::Result ManagedThread::TryInitializeUsingAutoStack(void (*f)(T*), const T& param, size_t stackSize, s32 priority, s32 coreNo)
972     {
973         return TryInitializeImplUsingAutoStack(
974                             TypeInfo(reinterpret_cast<T*>(NULL)),
975                             reinterpret_cast<ThreadFunc>(f),
976                             &param,
977                             stackSize,
978                             priority,
979                             coreNo );
980     }
981     template <typename T>
TryInitializeUsingAutoStack(void (* f)(const T *),const T & param,size_t stackSize,s32 priority,s32 coreNo)982     inline nn::Result ManagedThread::TryInitializeUsingAutoStack(void (*f)(const T*), const T& param, size_t stackSize, s32 priority, s32 coreNo)
983     {
984         return TryInitializeImplUsingAutoStack(
985                             TypeInfo(reinterpret_cast<T*>(NULL)),
986                             reinterpret_cast<ThreadFunc>(f),
987                             &param,
988                             stackSize,
989                             priority,
990                             coreNo );
991     }
TryInitializeUsingAutoStack(void (* f)(),size_t stackSize,s32 priority,s32 coreNo)992     inline nn::Result ManagedThread::TryInitializeUsingAutoStack(void (*f)(), size_t stackSize, s32 priority, s32 coreNo)
993     {
994         return TryInitializeUsingAutoStack(NoParameterFunc, f, stackSize, priority, coreNo);
995     }
996 
997     template <typename T, typename U>
InitializeUsingAutoStack(void (* f)(T),U param,size_t stackSize,s32 priority,s32 coreNo)998     inline void ManagedThread::InitializeUsingAutoStack(void (*f)(T), U param, size_t stackSize, s32 priority, s32 coreNo)
999     {
1000         NN_OS_ERROR_IF_FAILED(
1001             TryInitializeImplUsingAutoStack(
1002                 TypeInfo(reinterpret_cast<T*>(NULL), &param),
1003                 reinterpret_cast<ThreadFunc>(f),
1004                 &param,
1005                 stackSize,
1006                 priority,
1007                 coreNo ) );
1008     }
1009     template <typename T>
InitializeUsingAutoStack(void (* f)(T *),const T & param,size_t stackSize,s32 priority,s32 coreNo)1010     inline void ManagedThread::InitializeUsingAutoStack(void (*f)(T*), const T& param, size_t stackSize, s32 priority, s32 coreNo)
1011     {
1012         NN_OS_ERROR_IF_FAILED(
1013             TryInitializeImplUsingAutoStack(
1014                 TypeInfo(reinterpret_cast<T*>(NULL)),
1015                 reinterpret_cast<ThreadFunc>(f),
1016                 &param,
1017                 stackSize,
1018                 priority,
1019                 coreNo ) );
1020     }
1021     template <typename T>
InitializeUsingAutoStack(void (* f)(const T *),const T & param,size_t stackSize,s32 priority,s32 coreNo)1022     inline void ManagedThread::InitializeUsingAutoStack(void (*f)(const T*), const T& param, size_t stackSize, s32 priority, s32 coreNo)
1023     {
1024         NN_OS_ERROR_IF_FAILED(
1025             TryInitializeImplUsingAutoStack(
1026                 TypeInfo(reinterpret_cast<const T*>(NULL)),
1027                 reinterpret_cast<ThreadFunc>(f),
1028                 &param,
1029                 stackSize,
1030                 priority,
1031                 coreNo ) );
1032     }
InitializeUsingAutoStack(void (* f)(),size_t stackSize,s32 priority,s32 coreNo)1033     inline void ManagedThread::InitializeUsingAutoStack(void (*f)(), size_t stackSize, s32 priority, s32 coreNo)
1034     {
1035         InitializeUsingAutoStack(NoParameterFunc, f, stackSize, priority, coreNo);
1036     }
1037 
1038 
1039 
1040 
1041 #endif  // ifdef NN_SYSTEM_PROCESS
1042 
1043 
1044 
1045 }}
1046 
1047 
1048 #endif
1049 /* NN_OS_OS_MANAGEDTHREAD_H_ */
1050 #endif
1051 
1052