libctru  v2.3.1
thread.h
Go to the documentation of this file.
1 /**
2  * @file thread.h
3  * @brief Provides functions to use threads.
4  */
5 #pragma once
6 #include <3ds/types.h>
7 #include <3ds/result.h>
8 #include <3ds/synchronization.h>
9 #include <3ds/svc.h>
10 #include <3ds/errf.h>
11 
12 /// Makes the exception handler reuse the stack of the faulting thread as-is
13 #define RUN_HANDLER_ON_FAULTING_STACK ((void*)1)
14 
15 /// Makes the exception handler push the exception data on its stack
16 #define WRITE_DATA_TO_HANDLER_STACK NULL
17 
18 /// Makes the exception handler push the exception data on the stack of the faulting thread
19 #define WRITE_DATA_TO_FAULTING_STACK ((ERRF_ExceptionData*)1)
20 
21 /// libctru thread handle type
22 typedef struct Thread_tag* Thread;
23 
24 /// Exception handler type, necessarily an ARM function that does not return.
25 typedef void (*ExceptionHandler)(ERRF_ExceptionInfo* excep, CpuRegisters* regs);
26 
27 /**
28  * @brief Creates a new libctru thread.
29  * @param entrypoint The function that will be called first upon thread creation
30  * @param arg The argument passed to @p entrypoint
31  * @param stack_size The size of the stack that will be allocated for the thread (will be rounded to a multiple of 8 bytes)
32  * @param prio Low values gives the thread higher priority.
33  * For userland apps, this has to be within the range [0x18;0x3F].
34  * The main thread usually has a priority of 0x30, but not always. Use svcGetThreadPriority() if you need
35  * to create a thread with a priority that is explicitly greater or smaller than that of the main thread.
36  * @param core_id The ID of the processor the thread should be ran on. Processor IDs are labeled starting from 0.
37  * On Old3DS it must be <2, and on New3DS it must be <4.
38  * Pass -1 to execute the thread on all CPUs and -2 to execute the thread on the default CPU (read from the Exheader).
39  * @param detached When set to true, the thread is automatically freed when it finishes.
40  * @return The libctru thread handle on success, NULL on failure.
41  *
42  * - Processor #0 is the application core. It is always possible to create a thread on this core.
43  * - Processor #1 is the system core. If APT_SetAppCpuTimeLimit is used, it is possible to create a single thread on this core.
44  * - Processor #2 is New3DS exclusive. Normal applications can create threads on this core if the exheader kernel flags bitmask has 0x2000 set.
45  * - Processor #3 is New3DS exclusive. Normal applications cannot create threads on this core.
46  * - Processes in the BASE memory region can always create threads on processors #2 and #3.
47  *
48  * @note Default exit code of a thread is 0.
49  * @warning @ref svcExitThread should never be called from the thread, use @ref threadExit instead.
50  */
51 Thread threadCreate(ThreadFunc entrypoint, void* arg, size_t stack_size, int prio, int core_id, bool detached);
52 
53 /**
54  * @brief Retrieves the OS thread handle of a libctru thread.
55  * @param thread libctru thread handle
56  * @return OS thread handle
57  */
59 
60 /**
61  * @brief Retrieves the exit code of a finished libctru thread.
62  * @param thread libctru thread handle
63  * @return Exit code
64  */
66 
67 /**
68  * @brief Frees a finished libctru thread.
69  * @param thread libctru thread handle
70  * @remarks This function should not be called if the thread is detached, as it is freed automatically when it finishes.
71  */
72 void threadFree(Thread thread);
73 
74 /**
75  * @brief Waits for a libctru thread to finish (or returns immediately if it is already finished).
76  * @param thread libctru thread handle
77  * @param timeout_ns Timeout in nanoseconds. Pass U64_MAX if a timeout isn't desired
78  */
79 Result threadJoin(Thread thread, u64 timeout_ns);
80 
81 /**
82  * @brief Changes a thread's status from attached to detached.
83  * @param thread libctru thread handle
84  */
85 void threadDetach(Thread thread);
86 
87 /**
88  * @brief Retrieves the libctru thread handle of the current thread.
89  * @return libctru thread handle of the current thread, or NULL for the main thread
90  */
92 
93 /**
94  * @brief Exits the current libctru thread with an exit code (not usable from the main thread).
95  * @param rc Exit code
96  */
97 void threadExit(int rc) __attribute__((noreturn));
98 
99 /**
100  * @brief Sets the exception handler for the current thread. Called from the main thread, this sets the default handler.
101  * @param handler The exception handler, necessarily an ARM function that does not return
102  * @param stack_top A pointer to the top of the stack that will be used by the handler. See also @ref RUN_HANDLER_ON_FAULTING_STACK
103  * @param exception_data A pointer to the buffer that will contain the exception data.
104  See also @ref WRITE_DATA_TO_HANDLER_STACK and @ref WRITE_DATA_TO_FAULTING_STACK
105  *
106  * To have CPU exceptions reported through this mechanism, it is normally necessary that UNITINFO is set to a non-zero value when Kernel11 starts,
107  * and this mechanism is also controlled by @ref svcKernelSetState type 6, see 3dbrew.
108  *
109  * VFP exceptions are always reported this way even if the process is being debugged using the debug SVCs.
110  *
111  * The current thread need not be a libctru thread.
112  */
113 static inline void threadOnException(ExceptionHandler handler, void* stack_top, ERRF_ExceptionData* exception_data)
114 {
115  u8* tls = (u8*)getThreadLocalStorage();
116 
117  *(u32*)(tls + 0x40) = (u32)handler;
118  *(u32*)(tls + 0x44) = (u32)stack_top;
119  *(u32*)(tls + 0x48) = (u32)exception_data;
120 
121  __dsb();
122  __isb();
123 }
Error Display API.
__attribute__((warn_unused_result)) rbtree_node_t *rbtree_insert(rbtree_t *tree
Inserts a node into an rbtree.
3DS result code tools
Structure representing CPU registers.
Definition: types.h:63
Definition: errf.h:38
Definition: errf.h:28
Syscall wrappers.
static void * getThreadLocalStorage(void)
Gets the thread local storage buffer.
Definition: svc.h:531
Provides synchronization locks.
static void __dsb(void)
Performs a Data Synchronization Barrier operation.
Definition: synchronization.h:34
static void __isb(void)
Performs an Instruction Synchronization Barrier (officially "flush prefetch buffer") operation.
Definition: synchronization.h:46
struct Thread_tag * Thread
libctru thread handle type
Definition: thread.h:22
void(* ExceptionHandler)(ERRF_ExceptionInfo *excep, CpuRegisters *regs)
Exception handler type, necessarily an ARM function that does not return.
Definition: thread.h:25
Thread threadCreate(ThreadFunc entrypoint, void *arg, size_t stack_size, int prio, int core_id, bool detached)
Creates a new libctru thread.
Result threadJoin(Thread thread, u64 timeout_ns)
Waits for a libctru thread to finish (or returns immediately if it is already finished).
Handle threadGetHandle(Thread thread)
Retrieves the OS thread handle of a libctru thread.
void threadExit(int rc) __attribute__((noreturn))
Exits the current libctru thread with an exit code (not usable from the main thread).
Thread threadGetCurrent(void)
Retrieves the libctru thread handle of the current thread.
void threadDetach(Thread thread)
Changes a thread's status from attached to detached.
static void threadOnException(ExceptionHandler handler, void *stack_top, ERRF_ExceptionData *exception_data)
Sets the exception handler for the current thread.
Definition: thread.h:113
int threadGetExitCode(Thread thread)
Retrieves the exit code of a finished libctru thread.
void threadFree(Thread thread)
Frees a finished libctru thread.
Various system types.
uint64_t u64
64-bit unsigned integer
Definition: types.h:24
void(* ThreadFunc)(void *)
Thread entrypoint function.
Definition: types.h:43
uint8_t u8
would be nice if newlib had this already
Definition: types.h:21
u32 Handle
Resource handle.
Definition: types.h:41
s32 Result
Function result.
Definition: types.h:42
uint32_t u32
32-bit unsigned integer
Definition: types.h:23