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 31: |
Line 32: |
| |- | | |- |
| | 0x14 | | | 0x14 |
− | | [[KTimeableInterruptEvent|KThreadInterruptEvent]] | + | | [[KTimeableInterruptEvent]] |
− | | Used to suspend threads | + | | 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 | | | 0x34 |
| | u8 | | | u8 |
− | | Whether the thread is in the scheduler's queue and is ready to run | + | | Scheduling mask |
| |- | | |- |
| | 0x35 | | | 0x35 |
| | u8 | | | u8 |
− | | Used in syncing | + | | Set to 1 when a thread is woken up from a svcSendSyncRequest call due to the ServerSession endpoint closing down |
| |- | | |- |
| | 0x36 | | | 0x36 |
Line 56: |
Line 57: |
| | 0x37 | | | 0x37 |
| | u8 | | | u8 |
− | | Used in syncing | + | | Indicates there was an error translating the parameters in the command buffer during an IPC call |
| |- | | |- |
| | 0x38 | | | 0x38 |
Line 75: |
Line 76: |
| |- | | |- |
| | 0x48 | | | 0x48 |
− | | u32 | + | | KObjectMutex* |
− | | Double pointer to KThread of unknown use/creation - used in scheduler | + | | Locking kernel mutex |
| |- | | |- |
| | 0x4C | | | 0x4C |
Line 91: |
Line 92: |
| |- | | |- |
| | 0x5C | | | 0x5C |
− | | [[KSchedulableInterruptEvent|KMutexInterruptEvent]] * | + | | [[KMutex|KMutexLinkedList]] * |
| | Set in some very specific circumstances | | | Set in some very specific circumstances |
| |- | | |- |
Line 112: |
Line 113: |
| | 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 | | | 0x74 |
− | | u32 | + | | [[KResourceLimit|KPreemptionTimer]] * |
− | | ? | + | | Points to [[KResourceLimit]]+0x60, which among other things holds the amount of CPU time available in ticks, or NULL |
| |- | | |- |
| | 0x7C | | | 0x7C |
| | u8 | | | u8 |
− | | ? | + | | Thread is alive |
| |- | | |- |
| | 0x7D | | | 0x7D |
| | u8 | | | u8 |
− | | ? | + | | Thread has been terminated |
| |- | | |- |
| | 0x7E | | | 0x7E |
Line 159: |
Line 160: |
| |- | | |- |
| | 0xA0 | | | 0xA0 |
− | | KThread* | + | | KThreadLinkedListNode |
− | | Previous (virtual address) | + | | Previous and next scheduled threads |
− | |-
| |
− | | 0xA4
| |
− | | KThread*
| |
− | | Next (virtual address)
| |
| |- | | |- |
| | 0xA8 | | | 0xA8 |
− | | struct { KThread* first; KThread* last; } * ptr | + | | KThreadLinkedList * |
− | | Pointer to linked list that has stolen it, or 0 if in normal list | + | | Pointer to linked list of scheduled threads that has stolen it, or 0 if in normal list |
| |- | | |- |
| | 0xAC | | | 0xAC |
Line 175: |
Line 172: |
| |} | | |} |
| | | |
| + | 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" |
| + | |- |
| + | ! Value |
| + | ! Description |
| + | |- |
| + | | 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= | | =Thread Affinity Mask= |
| | | |