ReXGlue SDK
Loading...
Searching...
No Matches
rex::kernel::KernelThread Class Reference

#include <rex/kernel/object/kernel_thread.h>

Inheritance diagram for rex::kernel::KernelThread:
[legend]

Classes

struct  CreationParams

Public Member Functions

 KernelThread (TitleRuntime &runtime, u32 stack_size, u32 xapi_thread_startup, u32 start_address, u32 start_context, u32 creation_flags, bool guest_thread, bool main_thread=false, u32 title_process=0)
 KernelThread (TitleRuntime &runtime, u32 stack_size, u32 creation_flags, rex::MoveOnlyFunction< int()> host_fn)
 ~KernelThread ()
TitleRuntime & GetRuntime () const
kernel::GuestAddressSpace * GetAddressSpace () const
X_HANDLE GetHandle () const
u32 GetGuestObject () const
template<typename T>
T * GetGuestObject ()
const std::string & GetName () const
std::string_view GetCrashName () const
const CreationParams * GetCreationParams () const
u32 GetTLSPtr () const
u32 GetPCRPtr () const
bool IsGuestThread () const
bool IsMainThread () const override
bool IsRunning () const
u32 GetThreadID () const
u32 GetLastError () override
void SetLastError (u32 error_code) override
void SetName (const std::string_view name)
void Exit (int exit_code)
void RequestStop (i32 exit_code=0)
bool ForceStop ()
rex::platform::Fiber * GetMainFiber () const
void SetMainFiber (rex::platform::Fiber *fiber)
void EnterCriticalRegion ()
void LeaveCriticalRegion ()
void DeliverAPCs ()
bool HasPendingAPCs ()
void EnqueueAPC (u32 normal_routine, u32 normal_context, u32 arg1, u32 arg2)
i32 GetPriority () const
i32 GetHostPriority ()
void SetPriority (i32 increment)
bool SetAffinity (u32 affinity)
u8 GetActiveCPU () const
void SetActiveCPU (u8 cpu_index)
bool GetTLSValue (u32 slot, u32 *value_out) const
bool SetTLSValue (u32 slot, u32 value)
u32 GetSuspendCount ()
X_STATUS Resume (u32 *out_suspend_count=nullptr)
X_STATUS Suspend (u32 *out_suspend_count=nullptr)
X_STATUS Delay (u32 processor_mode, u32 alertable, u64 interval) const
rex::platform::Thread * GetThread ()
kernel::ThreadState * GetThreadState ()

Static Public Member Functions

static bool IsInThread (const KernelThread *other)
static bool IsInThread ()
static KernelThread * GetCallingThread ()
static u32 GetCurrentThreadHandle ()
static void CheckStop ()
static bool IsStopPending ()
static void SleepFor (std::chrono::microseconds duration)
static void WriteKernelTime ()

Public Attributes

PinCount pins

Static Public Attributes

static constexpr u32 kStackAddressRangeBegin = 0x70000000
static constexpr u32 kStackAddressRangeEnd = 0x7F000000

Protected Member Functions

void FreeStack ()
void InitializeGuestObject ()
void RundownAPCs ()
void CallThreadNotifyRoutines (bool create)
Protected Member Functions inherited from rex::NonCopyable
 NonCopyable (const NonCopyable &)=delete
NonCopyable & operator= (const NonCopyable &)=delete

Protected Attributes

CreationParams creation_params_ = {0, 0, 0, 0, 0, 0}
u32 thread_id_ = 0
u32 scratch_address_ = 0
u32 scratch_size_ = 0
u32 tls_static_address_ = 0
u32 tls_dynamic_address_ = 0
std::atomic< u32 > tls_slot_count_ {0}
u32 pcr_address_ = 0
u32 stack_alloc_base_ = 0
u32 stack_base_ = 0
u32 stack_limit_ = 0
bool guest_thread_ = false
bool main_thread_ = false
std::atomic< bool > running_ {false}
std::atomic< bool > exiting_ {false}
std::atomic< i32 > stop_exit_code_ {0}
std::mutex stop_mutex_
bool stop_requested_ = false
std::string thread_name_
std::array< char, 64 > crash_name_ {}
std::atomic< u8 > crash_name_length_ {0}
std::unique_ptr< kernel::ThreadState > thread_state_
i32 priority_ = 0
std::unique_ptr< SuspendWait > suspend_wait_
std::atomic< bool > suspend_deferred_ {false}
std::mutex thread_lock_
std::unique_ptr< rex::platform::Thread > thread_ = nullptr
rex::platform::Fiber * main_fiber_ = nullptr

Friends

class ThreadRegistry

Detailed Description

A guest thread or a host worker, owned by the thread registry.

Constructor & Destructor Documentation

◆ KernelThread() [1/2]

rex::kernel::KernelThread::KernelThread ( TitleRuntime & runtime,
u32 stack_size,
u32 xapi_thread_startup,
u32 start_address,
u32 start_context,
u32 creation_flags,
bool guest_thread,
bool main_thread = false,
u32 title_process = 0 )

Builds a guest KernelThread. The host thread starts when the registry launches the KernelThread.

Parameters
stack_sizeThe guest stack size, 0 for the process default.
xapi_thread_startupThe startup trampoline, or 0 for a raw thread.
creation_flagsThe creation flags, bit 0 creates the thread suspended.
guest_threadTrue for a thread created by the guest.
main_threadTrue for the entry point thread.
title_processThe title process block address, 0 for the title process.

◆ KernelThread() [2/2]

rex::kernel::KernelThread::KernelThread ( TitleRuntime & runtime,
u32 stack_size,
u32 creation_flags,
rex::MoveOnlyFunction< int()> host_fn )

Builds a host worker KernelThread.

Parameters
host_fnThe function the worker runs. Its result is the exit code.

◆ ~KernelThread()

rex::kernel::KernelThread::~KernelThread ( )

Frees the host thread, the scratch block, the stack, the PCR and the kernel thread block.

Member Function Documentation

◆ CheckStop()

void rex::kernel::KernelThread::CheckStop ( )
static

Throws rex::ThreadStop when the calling thread has a stop request or the title is terminating.

◆ Delay()

X_STATUS rex::kernel::KernelThread::Delay ( u32 processor_mode,
u32 alertable,
u64 interval ) const

Sleeps the calling thread.

Parameters
alertableTrue when the sleep ends on a user APC.
intervalThe interval in 100 nanosecond ticks, negative for relative.
Returns
X_STATUS_SUCCESS, or X_STATUS_USER_APC.

◆ EnterCriticalRegion()

void rex::kernel::KernelThread::EnterCriticalRegion ( )

Disables APC delivery by 1 level.

◆ Exit()

void rex::kernel::KernelThread::Exit ( int exit_code)

Exits the calling thread by unwinding to its entry.

◆ ForceStop()

bool rex::kernel::KernelThread::ForceStop ( )

Unwinds the thread to its entry when it runs recompiled code.

Returns
True when the thread now unwinds to its entry.

◆ GetCrashName()

std::string_view rex::kernel::KernelThread::GetCrashName ( ) const
inline

Returns the thread name without allocating or locking, for a crash report, cut to 63 characters.

◆ GetGuestObject()

template<typename T>
T * rex::kernel::KernelThread::GetGuestObject ( )
inline

Returns the thread block as a host pointer.

◆ GetHandle()

X_HANDLE rex::kernel::KernelThread::GetHandle ( ) const
inline
Returns
The handle, 0 before launch.

◆ GetLastError()

u32 rex::kernel::KernelThread::GetLastError ( )
overridevirtual

◆ GetTLSValue()

bool rex::kernel::KernelThread::GetTLSValue ( u32 slot,
u32 * value_out ) const
Parameters
value_outReceives the value.
Returns
True when the slot is in range.

◆ HasPendingAPCs()

bool rex::kernel::KernelThread::HasPendingAPCs ( )

Reports whether a user APC is queued and APC delivery is enabled.

Returns
True when the next alertable wait delivers an APC.

◆ IsMainThread()

bool rex::kernel::KernelThread::IsMainThread ( ) const
inlineoverridevirtual

Reports whether this is the entry point thread.

Implements rex::kernel::ICallingThread.

◆ IsStopPending()

bool rex::kernel::KernelThread::IsStopPending ( )
static

True when CheckStop would throw for the calling thread: it has a stop request, or it is a guest thread and the title is terminating. Takes no deferred suspend.

Returns
True when the calling thread must stop.

◆ LeaveCriticalRegion()

void rex::kernel::KernelThread::LeaveCriticalRegion ( )

Enables APC delivery by 1 level.

◆ RequestStop()

void rex::kernel::KernelThread::RequestStop ( i32 exit_code = 0)

Asks the thread to stop at its next wait or kernel call and wakes it.

◆ Resume()

X_STATUS rex::kernel::KernelThread::Resume ( u32 * out_suspend_count = nullptr)
Parameters
out_suspend_countReceives the previous count, may be null.
Returns
X_STATUS_SUCCESS, or X_STATUS_UNSUCCESSFUL.

◆ SetAffinity()

bool rex::kernel::KernelThread::SetAffinity ( u32 affinity)

Sets the affinity. Logical processors are 0 core 0 thread 0, 1 core 0 thread 1, 2 core 1 thread 0, 3 core 1 thread 1, 4 core 2 thread 0 and 5 core 2 thread 1.

Parameters
affinityProcessor mask. The highest set bit selects the processor.
Returns
False and no change when the mask is 0 or names a processor past the sixth.

◆ SetLastError()

void rex::kernel::KernelThread::SetLastError ( u32 error_code)
overridevirtual

◆ SetName()

void rex::kernel::KernelThread::SetName ( const std::string_view name)
Parameters
nameThe name. The handle is appended to it.

◆ SetTLSValue()

bool rex::kernel::KernelThread::SetTLSValue ( u32 slot,
u32 value )
Returns
True when the slot is in range.

◆ SleepFor()

void rex::kernel::KernelThread::SleepFor ( std::chrono::microseconds duration)
static

Sleeps the calling thread, waking early to stop when it has a stop request.

◆ Suspend()

X_STATUS rex::kernel::KernelThread::Suspend ( u32 * out_suspend_count = nullptr)
Parameters
out_suspend_countReceives the previous count, may be null.
Returns
X_STATUS_SUCCESS, or X_STATUS_UNSUCCESSFUL.

◆ WriteKernelTime()

void rex::kernel::KernelThread::WriteKernelTime ( )
static

Writes the CPU time of the calling thread to its KTHREAD, if it has a KernelThread.

Member Data Documentation

◆ crash_name_

std::array<char, 64> rex::kernel::KernelThread::crash_name_ {}
protected

Copy of the name cut to 63 characters, readable by a crash report without locking.

◆ exiting_

std::atomic<bool> rex::kernel::KernelThread::exiting_ {false}
protected

True once the thread began exiting, which makes CheckStop return without throwing.

◆ kStackAddressRangeBegin

u32 rex::kernel::KernelThread::kStackAddressRangeBegin = 0x70000000
staticconstexpr

Lowest guest address AllocateGuestStack places a stack at.

◆ kStackAddressRangeEnd

u32 rex::kernel::KernelThread::kStackAddressRangeEnd = 0x7F000000
staticconstexpr

Highest guest address AllocateGuestStack places a stack at, exclusive end of the range.

◆ pins

PinCount rex::kernel::KernelThread::pins

Transient pins that keep the object alive while a caller uses it.

◆ scratch_address_

u32 rex::kernel::KernelThread::scratch_address_ = 0
protected

Guest address of the scratch block that carries the arguments of APC kernel routine calls.

◆ scratch_size_

u32 rex::kernel::KernelThread::scratch_size_ = 0
protected

Size in bytes of the scratch block, 64.

◆ stack_base_

u32 rex::kernel::KernelThread::stack_base_ = 0
protected

Highest stack address, where the TLS block starts, stored in the PCR and the X_KTHREAD.

◆ stop_exit_code_

std::atomic<i32> rex::kernel::KernelThread::stop_exit_code_ {0}
protected

Exit code carried by the ThreadStop exception that ends the thread.

◆ stop_mutex_

std::mutex rex::kernel::KernelThread::stop_mutex_
protected

Guards stop_requested_, thread_ and thread_state_ against a concurrent stop request.

◆ stop_requested_

bool rex::kernel::KernelThread::stop_requested_ = false
protected

True once a stop was requested, applied to the thread state when it is created.

◆ suspend_deferred_

std::atomic<bool> rex::kernel::KernelThread::suspend_deferred_ {false}
protected

True when Suspend could not stop the thread, which suspends itself at its next CheckStop.

◆ suspend_wait_

std::unique_ptr<SuspendWait> rex::kernel::KernelThread::suspend_wait_
protected

Holds the mutex that guards the suspend count in the X_KTHREAD and suspend_deferred_, and the condition variable Resume signals to release a thread waiting in a deferred suspend.

◆ thread_lock_

std::mutex rex::kernel::KernelThread::thread_lock_
protected

Guards thread_name_, crash_name_ and the host thread name.

◆ tls_slot_count_

std::atomic<u32> rex::kernel::KernelThread::tls_slot_count_ {0}
protected

Number of 4 byte dynamic TLS slots, read by the TLS accessors for bounds checks.


The documentation for this class was generated from the following file: