From baed7e1fba99c3f1932c6a41ad1496d1b6490a5a Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 3 Oct 2018 18:47:57 -0400 Subject: kernel/thread: Make all instance variables private Many of the member variables of the thread class aren't even used outside of the class itself, so there's no need to make those variables public. This change follows in the steps of the previous changes that made other kernel types' members private. The main motivation behind this is that the Thread class will likely change in the future as emulation becomes more accurate, and letting random bits of the emulator access data members of the Thread class directly makes it a pain to shuffle around and/or modify internals. Having all data members public like this also makes it difficult to reason about certain bits of behavior without first verifying what parts of the core actually use them. Everything being public also generally follows the tendency for changes to be introduced in completely different translation units that would otherwise be better introduced as an addition to the Thread class' public interface. --- src/core/hle/kernel/thread.h | 216 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 181 insertions(+), 35 deletions(-) (limited to 'src/core/hle/kernel/thread.h') diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 4250144c3..d2b191357 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -65,6 +65,15 @@ public: using TLSMemory = std::vector; using TLSMemoryPtr = std::shared_ptr; + using MutexWaitingThreads = std::vector>; + + using ThreadContext = Core::ARM_Interface::ThreadContext; + + using ThreadWaitObjects = std::vector>; + + using WakeupCallback = std::function thread, + SharedPtr object, std::size_t index)>; + /** * Creates and returns a new thread. The new thread is immediately scheduled * @param kernel The kernel instance this thread will be created under. @@ -105,6 +114,14 @@ public: return current_priority; } + /** + * Gets the thread's nominal priority. + * @return The current thread's nominal priority. + */ + u32 GetNominalPriority() const { + return nominal_priority; + } + /** * Sets the thread's current priority * @param priority The new priority @@ -133,7 +150,7 @@ public: * Gets the thread's thread ID * @return The thread's ID */ - u32 GetThreadId() const { + u32 GetThreadID() const { return thread_id; } @@ -203,6 +220,11 @@ public: return tpidr_el0; } + /// Sets the value of the TPIDR_EL0 Read/Write system register for this thread. + void SetTPIDR_EL0(u64 value) { + tpidr_el0 = value; + } + /* * Returns the address of the current thread's command buffer, located in the TLS. * @returns VAddr of the thread's command buffer. @@ -218,69 +240,193 @@ public: return status == ThreadStatus::WaitSynchAll; } - Core::ARM_Interface::ThreadContext context; + ThreadContext& GetContext() { + return context; + } + + const ThreadContext& GetContext() const { + return context; + } + + ThreadStatus GetStatus() const { + return status; + } + + void SetStatus(ThreadStatus new_status); + + u64 GetLastRunningTicks() const { + return last_running_ticks; + } + + s32 GetProcessorID() const { + return processor_id; + } + + SharedPtr& GetOwnerProcess() { + return owner_process; + } + + const SharedPtr& GetOwnerProcess() const { + return owner_process; + } + + const ThreadWaitObjects& GetWaitObjects() const { + return wait_objects; + } + + void SetWaitObjects(ThreadWaitObjects objects) { + wait_objects = std::move(objects); + } + + void ClearWaitObjects() { + wait_objects.clear(); + } + + /// Determines whether all the objects this thread is waiting on are ready. + bool AllWaitObjectsReady(); + + const MutexWaitingThreads& GetMutexWaitingThreads() const { + return wait_mutex_threads; + } + + Thread* GetLockOwner() const { + return lock_owner.get(); + } + + void SetLockOwner(SharedPtr owner) { + lock_owner = std::move(owner); + } + + VAddr GetCondVarWaitAddress() const { + return condvar_wait_address; + } + + void SetCondVarWaitAddress(VAddr address) { + condvar_wait_address = address; + } + + VAddr GetMutexWaitAddress() const { + return mutex_wait_address; + } - u32 thread_id; + void SetMutexWaitAddress(VAddr address) { + mutex_wait_address = address; + } - ThreadStatus status; - VAddr entry_point; - VAddr stack_top; + Handle GetWaitHandle() const { + return wait_handle; + } - u32 nominal_priority; ///< Nominal thread priority, as set by the emulated application - u32 current_priority; ///< Current thread priority, can be temporarily changed + void SetWaitHandle(Handle handle) { + wait_handle = handle; + } - u64 last_running_ticks; ///< CPU tick when thread was last running + VAddr GetArbiterWaitAddress() const { + return arb_wait_address; + } - s32 processor_id; + void SetArbiterWaitAddress(VAddr address) { + arb_wait_address = address; + } - VAddr tls_address; ///< Virtual address of the Thread Local Storage of the thread - u64 tpidr_el0; ///< TPIDR_EL0 read/write system register. + void SetGuestHandle(Handle handle) { + guest_handle = handle; + } - SharedPtr owner_process; ///< Process that owns this thread + bool HasWakeupCallback() const { + return wakeup_callback != nullptr; + } + + void SetWakeupCallback(WakeupCallback callback) { + wakeup_callback = std::move(callback); + } + + void InvalidateWakeupCallback() { + SetWakeupCallback(nullptr); + } + + /** + * Invokes the thread's wakeup callback. + * + * @pre A valid wakeup callback has been set. Violating this precondition + * will cause an assertion to trigger. + */ + bool InvokeWakeupCallback(ThreadWakeupReason reason, SharedPtr thread, + SharedPtr object, std::size_t index); + + u32 GetIdealCore() const { + return ideal_core; + } + + u64 GetAffinityMask() const { + return affinity_mask; + } + +private: + explicit Thread(KernelCore& kernel); + ~Thread() override; + + Core::ARM_Interface::ThreadContext context{}; + + u32 thread_id = 0; + + ThreadStatus status = ThreadStatus::Dormant; + + VAddr entry_point = 0; + VAddr stack_top = 0; + + u32 nominal_priority = 0; ///< Nominal thread priority, as set by the emulated application + u32 current_priority = 0; ///< Current thread priority, can be temporarily changed + + u64 last_running_ticks = 0; ///< CPU tick when thread was last running + + s32 processor_id = 0; + + VAddr tls_address = 0; ///< Virtual address of the Thread Local Storage of the thread + u64 tpidr_el0 = 0; ///< TPIDR_EL0 read/write system register. + + /// Process that owns this thread + SharedPtr owner_process; /// Objects that the thread is waiting on, in the same order as they were - // passed to WaitSynchronization1/N. - std::vector> wait_objects; + /// passed to WaitSynchronization1/N. + ThreadWaitObjects wait_objects; /// List of threads that are waiting for a mutex that is held by this thread. - std::vector> wait_mutex_threads; + MutexWaitingThreads wait_mutex_threads; /// Thread that owns the lock that this thread is waiting for. SharedPtr lock_owner; - // If waiting on a ConditionVariable, this is the ConditionVariable address - VAddr condvar_wait_address; - VAddr mutex_wait_address; ///< If waiting on a Mutex, this is the mutex address - Handle wait_handle; ///< The handle used to wait for the mutex. + /// If waiting on a ConditionVariable, this is the ConditionVariable address + VAddr condvar_wait_address = 0; + /// If waiting on a Mutex, this is the mutex address + VAddr mutex_wait_address = 0; + /// The handle used to wait for the mutex. + Handle wait_handle = 0; - // If waiting for an AddressArbiter, this is the address being waited on. + /// If waiting for an AddressArbiter, this is the address being waited on. VAddr arb_wait_address{0}; - std::string name; - /// Handle used by guest emulated application to access this thread - Handle guest_handle; + Handle guest_handle = 0; /// Handle used as userdata to reference this object when inserting into the CoreTiming queue. - Handle callback_handle; + Handle callback_handle = 0; - using WakeupCallback = bool(ThreadWakeupReason reason, SharedPtr thread, - SharedPtr object, std::size_t index); - // Callback that will be invoked when the thread is resumed from a waiting state. If the thread - // was waiting via WaitSynchronizationN then the object will be the last object that became - // available. In case of a timeout, the object will be nullptr. - std::function wakeup_callback; + /// Callback that will be invoked when the thread is resumed from a waiting state. If the thread + /// was waiting via WaitSynchronizationN then the object will be the last object that became + /// available. In case of a timeout, the object will be nullptr. + WakeupCallback wakeup_callback; std::shared_ptr scheduler; u32 ideal_core{0xFFFFFFFF}; u64 affinity_mask{0x1}; -private: - explicit Thread(KernelCore& kernel); - ~Thread() override; - TLSMemoryPtr tls_memory = std::make_shared(); + + std::string name; }; /** -- cgit v1.2.3