Difference between revisions of "KThread"

From 3dbrew
Jump to navigation Jump to search
 
(45 intermediate revisions by 4 users not shown)
Line 1: Line 1:
[[Category:Kernel objects]]
+
[[Category:Kernel synchronization objects]]
class [[KThread]] extends [[KSynchronizationObject]];
+
[[Category:Kernel interrupt events]]
 +
class [[KThread]] extends [[KSynchronizationObject]], [[KTimeableInterruptEvent]], [[KSendableInterruptEvent]] and [[KSchedulableInterruptEvent]];
  
 
Size : 0xB0 bytes
 
Size : 0xB0 bytes
Line 6: Line 7:
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Offset
+
! Offset
 
! Type
 
! Type
! Description
+
! Description
 
|-
 
|-
 
| 0x0
 
| 0x0
Line 17: Line 18:
 
| u32
 
| u32
 
| Reference count
 
| Reference count
 +
|-
 +
| 0x8
 +
| u32
 +
| Count of KThreads that sync with this object - number of nodes in the linked list below
 +
|-
 +
| 0xC
 +
| KLinkedListNode*
 +
| Pointer to first KLinkedListNode in node list of KThreads that sync with this object
 +
|-
 +
| 0x10
 +
| KLinkedListNode*
 +
| Pointer to last KLinkedListNode in node list of KThreads that sync with this object
 
|-
 
|-
 
| 0x14
 
| 0x14
| u32
+
| [[KTimeableInterruptEvent]]
| Start of 0x10 byte unnamed kernel object in KThread
+
| Used to suspend threads (*this)
 
|-
 
|-
 
| 0x24
 
| 0x24
| u32
+
| [[KSendableInterruptEvent]]
| Start of 0x8 byte unnamed kernel object in KThread
+
| Interrupt event (*this) sent to terminate a thread, except in the case just below
 
|-
 
|-
 
| 0x2C
 
| 0x2C
| u32
+
| [[KSchedulableInterruptEvent]]
| Start of unnamed kernel object of undetermined size in KThread
+
| Interrupt event (*this) scheduled by the IRQ handler when the thread should terminate (*this)
 +
|-
 +
| 0x34
 +
| u8
 +
| Scheduling mask
 +
|-
 +
| 0x35
 +
| u8
 +
| Set to 1 when a thread is woken up from a svcSendSyncRequest call due to the ServerSession endpoint closing down
 +
|-
 +
| 0x36
 +
| s8
 +
| Indicates that the thread shall terminate
 +
|-
 +
| 0x37
 +
| u8
 +
| Indicates there was an error translating the parameters in the command buffer during an IPC call
 +
|-
 +
| 0x38
 +
| KDebugThread*
 +
| Pointer to KDebugThread object used with the current KThread
 
|-
 
|-
 
| 0x3C
 
| 0x3C
 
| u32
 
| u32
| Thread priority
+
| Base thread priority
 
|-
 
|-
 
| 0x40
 
| 0x40
 
| u32
 
| u32
 
| Pointer to object the KThread is waiting on- can be a timer, event, session, etc.
 
| Pointer to object the KThread is waiting on- can be a timer, event, session, etc.
 +
|-
 +
| 0x44
 +
| Result
 +
| Status for object above
 
|-
 
|-
 
| 0x48
 
| 0x48
| u32
+
| KObjectMutex*
| Double pointer to KThread of unknown use/creation - used in scheduler
+
| Locking kernel mutex
 
|-
 
|-
 
| 0x4C
 
| 0x4C
 
| u32
 
| u32
 
| Arbitration address
 
| Arbitration address
 +
|-
 +
| 0x50
 +
| KLinkedListNode*
 +
| Pointer to first KLinkedListNode in node list of objects this thread is waiting on
 +
|-
 +
| 0x54
 +
| KLinkedListNode*
 +
| Pointer to last KLinkedListNode in node list of objects this thread is
 
|-
 
|-
 
| 0x5C
 
| 0x5C
 +
| [[KMutex|KMutexLinkedList]] *
 +
| Set in some very specific circumstances
 +
|-
 +
| 0x60
 +
| u32
 +
| Count of KMutex objects this thread is using
 +
|-
 +
| 0x64
 
| KLinkedListNode*
 
| KLinkedListNode*
| Objects the Thread waits for?
+
| Pointer to first KLinkedListNode in node list of KMutex objects this thread is using
 +
|-
 +
| 0x68
 +
| KLinkedListNode*
 +
| Pointer to last KLinkedListNode in node list of KMutex objects this thread is using
 
|-
 
|-
 
| 0x6C
 
| 0x6C
 
| s32
 
| s32
| Thread priority
+
| Dynamic thread priority
 
|-
 
|-
 
| 0x70
 
| 0x70
 
| s32
 
| s32
| Processor that created the thread
+
| Processor that created the thread (in the sense of "first ran") ; processor the thread is running in
 +
|-
 +
| 0x74
 +
| [[KResourceLimit|KPreemptionTimer]] *
 +
| Points to [[KResourceLimit]]+0x60, which among other things holds the amount of CPU time available in ticks, or NULL
 +
|-
 +
| 0x7C
 +
| u8
 +
| Thread is alive
 +
|-
 +
| 0x7D
 +
| u8
 +
| Thread has been terminated
 
|-
 
|-
 
| 0x7E
 
| 0x7E
 
| u8
 
| u8
| Thread type - kernel threads are 0-2 and are assigned values based on where in the kernel the thread is created.  All threads created outside the kernel environment are type 3.
+
| Thread affinity mask - set differently depending on whether the thread is created via svc call or from inside the kernel
 
|-
 
|-
 
| 0x80
 
| 0x80
Line 72: Line 141:
 
| 0x88
 
| 0x88
 
| u32*
 
| u32*
| Ptr to svc mode register storage for KThread.
+
| Ptr to svc mode register storage for KThread inside the thread context.
 
|-
 
|-
 
| 0x8C
 
| 0x8C
 
| u32*
 
| u32*
| End-address of the page for this thread allocated in the [[Memory_layout|0xFF4XX000]] region. Thus, if the beginning of this mapped page is 0xFF401000, this ptr would be 0xFF402000.  Thread context page - used for thread svc stack, preserving svc mode registers and VFP exception register for thread.
+
| End-address of the page for this thread context allocated in the [[Memory_layout|0xFF4XX000]] region. Thus, if the beginning of this mapped page is 0xFF401000, this ptr would be 0xFF402000.  Thread context page - used for thread svc stack, preserving svc mode registers and VFP exception register for thread.
 
|-
 
|-
 
| 0x90
 
| 0x90
Line 84: Line 153:
 
| 0x94
 
| 0x94
 
| void*
 
| void*
| Ptr to threadlocalstorage
+
| Ptr to [[Thread Local Storage]]
 
|-
 
|-
 
| 0x98
 
| 0x98
 
| void*
 
| void*
| Ptr to threadlocalstorage in FCRAM via kernel vmem
+
| Ptr to [[Thread Local Storage]] in FCRAM via kernel vmem
 
|-
 
|-
 
| 0xA0
 
| 0xA0
| KThread*
+
| KThreadLinkedListNode
| Previous (virtual address)
+
| Previous and next scheduled threads
 +
|-
 +
| 0xA8
 +
| KThreadLinkedList *
 +
| Pointer to linked list of scheduled threads that has stolen it, or 0 if in normal list
 
|-
 
|-
| 0xA4
+
| 0xAC
| KThread*
+
| s32
| Next (virtual address)
+
| Priority to restore after sleep if suspended, otherwise -1
 +
|}
 +
 
 +
With the following declarations: <code>struct KThreadLinkedList { KThread *first, *last; };</code> and <code>struct KThreadLinkedListNode { KThread *prev, *next; };</code>.
 +
 
 +
=Thread Scheduling Mask=
 +
The thread scheduling mask is made of a low nibble (enum) and a high nibble (bitfield).
 +
 
 +
Low nibble:
 +
 
 +
{| class="wikitable" border="1"
 
|-
 
|-
| 0xA8
+
! Value
| struct { KThread* first; KThread* last; } ptr
+
! Description
| Pointer to linked list that has stolen it, or 0 if in normal list
+
|-
 +
| 0
 +
| The thread is not scheduled
 +
|-
 +
| 1
 +
| The thread is scheduled
 +
|-
 +
| 2
 +
| The thread is being terminated
 +
|}
 +
 
 +
High nibble:
 +
{| class="wikitable" border="1"
 +
|-
 +
! Mask
 +
! Description
 +
|-
 +
| 0
 +
| Nothing special
 +
|-
 +
| 0x8 (bit 3)
 +
| The thread has been debug-locked
 
|}
 
|}
 +
 +
A thread is scheduled *if and only if* its (full) scheduling mask is exactly 1. This allows debug-(un)locking of threads to be done transparently.
 +
=Thread Affinity Mask=
 +
 +
If the thread is created via a call to SVC 8(CreateThread), which uses thread creation type 3, and the CPU ID is -2(meaning use the core specified in the exheader), the mask is just the affinity mask from the thread's owner KProcess.  If the CPU ID is -1(meaning any core), the affinity mask is set to 0xF on the New3DS and 0x3 on the Old3DS.  Otherwise, the affinity mask is (1 << cpu_id) | 1.
 +
 +
If the thread is created via a call by the kernel, which uses thread creation types 0-2, the checks for -1 and -2 are skipped and the mask is always (1 << cpu_id) | 1.

Latest revision as of 00:48, 22 May 2020

class KThread extends KSynchronizationObject, KTimeableInterruptEvent, KSendableInterruptEvent and KSchedulableInterruptEvent;

Size : 0xB0 bytes

Offset Type Description
0x0 u32 Pointer to vtable
0x4 u32 Reference count
0x8 u32 Count of KThreads that sync with this object - number of nodes in the linked list below
0xC KLinkedListNode* Pointer to first KLinkedListNode in node list of KThreads that sync with this object
0x10 KLinkedListNode* Pointer to last KLinkedListNode in node list of KThreads that sync with this object
0x14 KTimeableInterruptEvent Used to suspend threads (*this)
0x24 KSendableInterruptEvent Interrupt event (*this) sent to terminate a thread, except in the case just below
0x2C KSchedulableInterruptEvent Interrupt event (*this) scheduled by the IRQ handler when the thread should terminate (*this)
0x34 u8 Scheduling mask
0x35 u8 Set to 1 when a thread is woken up from a svcSendSyncRequest call due to the ServerSession endpoint closing down
0x36 s8 Indicates that the thread shall terminate
0x37 u8 Indicates there was an error translating the parameters in the command buffer during an IPC call
0x38 KDebugThread* Pointer to KDebugThread object used with the current KThread
0x3C u32 Base thread priority
0x40 u32 Pointer to object the KThread is waiting on- can be a timer, event, session, etc.
0x44 Result Status for object above
0x48 KObjectMutex* Locking kernel mutex
0x4C u32 Arbitration address
0x50 KLinkedListNode* Pointer to first KLinkedListNode in node list of objects this thread is waiting on
0x54 KLinkedListNode* Pointer to last KLinkedListNode in node list of objects this thread is
0x5C KMutexLinkedList * Set in some very specific circumstances
0x60 u32 Count of KMutex objects this thread is using
0x64 KLinkedListNode* Pointer to first KLinkedListNode in node list of KMutex objects this thread is using
0x68 KLinkedListNode* Pointer to last KLinkedListNode in node list of KMutex objects this thread is using
0x6C s32 Dynamic thread priority
0x70 s32 Processor that created the thread (in the sense of "first ran") ; processor the thread is running in
0x74 KPreemptionTimer * Points to KResourceLimit+0x60, which among other things holds the amount of CPU time available in ticks, or NULL
0x7C u8 Thread is alive
0x7D u8 Thread has been terminated
0x7E u8 Thread affinity mask - set differently depending on whether the thread is created via svc call or from inside the kernel
0x80 KProcess* Process the thread belongs to (virtual address)
0x84 u32 Thread id
0x88 u32* Ptr to svc mode register storage for KThread inside the thread context.
0x8C u32* End-address of the page for this thread context allocated in the 0xFF4XX000 region. Thus, if the beginning of this mapped page is 0xFF401000, this ptr would be 0xFF402000. Thread context page - used for thread svc stack, preserving svc mode registers and VFP exception register for thread.
0x90 s32 Ideal processor (processorid value from svcCreateThread)
0x94 void* Ptr to Thread Local Storage
0x98 void* Ptr to Thread Local Storage in FCRAM via kernel vmem
0xA0 KThreadLinkedListNode Previous and next scheduled threads
0xA8 KThreadLinkedList * Pointer to linked list of scheduled threads that has stolen it, or 0 if in normal list
0xAC s32 Priority to restore after sleep if suspended, otherwise -1

With the following declarations: struct KThreadLinkedList { KThread *first, *last; }; and struct KThreadLinkedListNode { KThread *prev, *next; };.

Thread Scheduling Mask[edit]

The thread scheduling mask is made of a low nibble (enum) and a high nibble (bitfield).

Low nibble:

Value Description
0 The thread is not scheduled
1 The thread is scheduled
2 The thread is being terminated

High nibble:

Mask Description
0 Nothing special
0x8 (bit 3) The thread has been debug-locked

A thread is scheduled *if and only if* its (full) scheduling mask is exactly 1. This allows debug-(un)locking of threads to be done transparently.

Thread Affinity Mask[edit]

If the thread is created via a call to SVC 8(CreateThread), which uses thread creation type 3, and the CPU ID is -2(meaning use the core specified in the exheader), the mask is just the affinity mask from the thread's owner KProcess. If the CPU ID is -1(meaning any core), the affinity mask is set to 0xF on the New3DS and 0x3 on the Old3DS. Otherwise, the affinity mask is (1 << cpu_id) | 1.

If the thread is created via a call by the kernel, which uses thread creation types 0-2, the checks for -1 and -2 are skipped and the mask is always (1 << cpu_id) | 1.