mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-10-30 15:39:02 -05:00 
			
		
		
		
	kernel: Replace usage of boost::intrusive_ptr with std::shared_ptr for kernel objects. (#3154)
* kernel: Replace usage of boost::intrusive_ptr with std::shared_ptr for kernel objects. - See https://github.com/citra-emu/citra/pull/4710 for details.
This commit is contained in:
		| @@ -21,7 +21,7 @@ | ||||
| namespace Kernel { | ||||
| namespace { | ||||
| // Wake up num_to_wake (or all) threads in a vector. | ||||
| void WakeThreads(const std::vector<SharedPtr<Thread>>& waiting_threads, s32 num_to_wake) { | ||||
| void WakeThreads(const std::vector<std::shared_ptr<Thread>>& waiting_threads, s32 num_to_wake) { | ||||
|     auto& system = Core::System::GetInstance(); | ||||
|     // Only process up to 'target' threads, unless 'target' is <= 0, in which case process | ||||
|     // them all. | ||||
| @@ -59,7 +59,8 @@ ResultCode AddressArbiter::SignalToAddress(VAddr address, SignalType type, s32 v | ||||
| } | ||||
|  | ||||
| ResultCode AddressArbiter::SignalToAddressOnly(VAddr address, s32 num_to_wake) { | ||||
|     const std::vector<SharedPtr<Thread>> waiting_threads = GetThreadsWaitingOnAddress(address); | ||||
|     const std::vector<std::shared_ptr<Thread>> waiting_threads = | ||||
|         GetThreadsWaitingOnAddress(address); | ||||
|     WakeThreads(waiting_threads, num_to_wake); | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
| @@ -87,7 +88,8 @@ ResultCode AddressArbiter::ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr a | ||||
|     } | ||||
|  | ||||
|     // Get threads waiting on the address. | ||||
|     const std::vector<SharedPtr<Thread>> waiting_threads = GetThreadsWaitingOnAddress(address); | ||||
|     const std::vector<std::shared_ptr<Thread>> waiting_threads = | ||||
|         GetThreadsWaitingOnAddress(address); | ||||
|  | ||||
|     // Determine the modified value depending on the waiting count. | ||||
|     s32 updated_value; | ||||
| @@ -172,21 +174,21 @@ ResultCode AddressArbiter::WaitForAddressIfEqual(VAddr address, s32 value, s64 t | ||||
| } | ||||
|  | ||||
| ResultCode AddressArbiter::WaitForAddressImpl(VAddr address, s64 timeout) { | ||||
|     SharedPtr<Thread> current_thread = system.CurrentScheduler().GetCurrentThread(); | ||||
|     Thread* current_thread = system.CurrentScheduler().GetCurrentThread(); | ||||
|     current_thread->SetArbiterWaitAddress(address); | ||||
|     current_thread->SetStatus(ThreadStatus::WaitArb); | ||||
|     current_thread->InvalidateWakeupCallback(); | ||||
|  | ||||
|     current_thread->WakeAfterDelay(timeout); | ||||
|  | ||||
|     system.PrepareReschedule(current_thread->GetProcessorID()); | ||||
|     return RESULT_TIMEOUT; | ||||
| } | ||||
|  | ||||
| std::vector<SharedPtr<Thread>> AddressArbiter::GetThreadsWaitingOnAddress(VAddr address) const { | ||||
| std::vector<std::shared_ptr<Thread>> AddressArbiter::GetThreadsWaitingOnAddress( | ||||
|     VAddr address) const { | ||||
|  | ||||
|     // Retrieve all threads that are waiting for this address. | ||||
|     std::vector<SharedPtr<Thread>> threads; | ||||
|     std::vector<std::shared_ptr<Thread>> threads; | ||||
|     const auto& scheduler = system.GlobalScheduler(); | ||||
|     const auto& thread_list = scheduler.GetThreadList(); | ||||
|  | ||||
| @@ -198,7 +200,7 @@ std::vector<SharedPtr<Thread>> AddressArbiter::GetThreadsWaitingOnAddress(VAddr | ||||
|  | ||||
|     // Sort them by priority, such that the highest priority ones come first. | ||||
|     std::sort(threads.begin(), threads.end(), | ||||
|               [](const SharedPtr<Thread>& lhs, const SharedPtr<Thread>& rhs) { | ||||
|               [](const std::shared_ptr<Thread>& lhs, const std::shared_ptr<Thread>& rhs) { | ||||
|                   return lhs->GetPriority() < rhs->GetPriority(); | ||||
|               }); | ||||
|  | ||||
|   | ||||
| @@ -72,7 +72,7 @@ private: | ||||
|     ResultCode WaitForAddressImpl(VAddr address, s64 timeout); | ||||
|  | ||||
|     // Gets the threads waiting on an address. | ||||
|     std::vector<SharedPtr<Thread>> GetThreadsWaitingOnAddress(VAddr address) const; | ||||
|     std::vector<std::shared_ptr<Thread>> GetThreadsWaitingOnAddress(VAddr address) const; | ||||
|  | ||||
|     Core::System& system; | ||||
| }; | ||||
|   | ||||
| @@ -15,11 +15,11 @@ namespace Kernel { | ||||
| ClientPort::ClientPort(KernelCore& kernel) : Object{kernel} {} | ||||
| ClientPort::~ClientPort() = default; | ||||
|  | ||||
| SharedPtr<ServerPort> ClientPort::GetServerPort() const { | ||||
| std::shared_ptr<ServerPort> ClientPort::GetServerPort() const { | ||||
|     return server_port; | ||||
| } | ||||
|  | ||||
| ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() { | ||||
| ResultVal<std::shared_ptr<ClientSession>> ClientPort::Connect() { | ||||
|     // Note: Threads do not wait for the server endpoint to call | ||||
|     // AcceptSession before returning from this call. | ||||
|  | ||||
| @@ -29,7 +29,8 @@ ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() { | ||||
|     active_sessions++; | ||||
|  | ||||
|     // Create a new session pair, let the created sessions inherit the parent port's HLE handler. | ||||
|     auto [server, client] = ServerSession::CreateSessionPair(kernel, server_port->GetName(), this); | ||||
|     auto [server, client] = | ||||
|         ServerSession::CreateSessionPair(kernel, server_port->GetName(), SharedFrom(this)); | ||||
|  | ||||
|     if (server_port->HasHLEHandler()) { | ||||
|         server_port->GetHLEHandler()->ClientConnected(server); | ||||
|   | ||||
| @@ -17,6 +17,9 @@ class ServerPort; | ||||
|  | ||||
| class ClientPort final : public Object { | ||||
| public: | ||||
|     explicit ClientPort(KernelCore& kernel); | ||||
|     ~ClientPort() override; | ||||
|  | ||||
|     friend class ServerPort; | ||||
|     std::string GetTypeName() const override { | ||||
|         return "ClientPort"; | ||||
| @@ -30,7 +33,7 @@ public: | ||||
|         return HANDLE_TYPE; | ||||
|     } | ||||
|  | ||||
|     SharedPtr<ServerPort> GetServerPort() const; | ||||
|     std::shared_ptr<ServerPort> GetServerPort() const; | ||||
|  | ||||
|     /** | ||||
|      * Creates a new Session pair, adds the created ServerSession to the associated ServerPort's | ||||
| @@ -38,7 +41,7 @@ public: | ||||
|      * waiting on it to awake. | ||||
|      * @returns ClientSession The client endpoint of the created Session pair, or error code. | ||||
|      */ | ||||
|     ResultVal<SharedPtr<ClientSession>> Connect(); | ||||
|     ResultVal<std::shared_ptr<ClientSession>> Connect(); | ||||
|  | ||||
|     /** | ||||
|      * Signifies that a previously active connection has been closed, | ||||
| @@ -47,10 +50,7 @@ public: | ||||
|     void ConnectionClosed(); | ||||
|  | ||||
| private: | ||||
|     explicit ClientPort(KernelCore& kernel); | ||||
|     ~ClientPort() override; | ||||
|  | ||||
|     SharedPtr<ServerPort> server_port; ///< ServerPort associated with this client port. | ||||
|     std::shared_ptr<ServerPort> server_port; ///< ServerPort associated with this client port. | ||||
|     u32 max_sessions = 0;    ///< Maximum number of simultaneous sessions the port can have | ||||
|     u32 active_sessions = 0; ///< Number of currently open sessions to this port | ||||
|     std::string name;        ///< Name of client port (optional) | ||||
|   | ||||
| @@ -16,25 +16,20 @@ ClientSession::ClientSession(KernelCore& kernel) : Object{kernel} {} | ||||
| ClientSession::~ClientSession() { | ||||
|     // This destructor will be called automatically when the last ClientSession handle is closed by | ||||
|     // the emulated application. | ||||
|  | ||||
|     // A local reference to the ServerSession is necessary to guarantee it | ||||
|     // will be kept alive until after ClientDisconnected() returns. | ||||
|     SharedPtr<ServerSession> server = parent->server; | ||||
|     if (server) { | ||||
|         server->ClientDisconnected(); | ||||
|     if (parent->server) { | ||||
|         parent->server->ClientDisconnected(); | ||||
|     } | ||||
|  | ||||
|     parent->client = nullptr; | ||||
| } | ||||
|  | ||||
| ResultCode ClientSession::SendSyncRequest(SharedPtr<Thread> thread) { | ||||
| ResultCode ClientSession::SendSyncRequest(Thread* thread) { | ||||
|     // Keep ServerSession alive until we're done working with it. | ||||
|     SharedPtr<ServerSession> server = parent->server; | ||||
|     if (server == nullptr) | ||||
|     if (parent->server == nullptr) | ||||
|         return ERR_SESSION_CLOSED_BY_REMOTE; | ||||
|  | ||||
|     // Signal the server session that new data is available | ||||
|     return server->HandleSyncRequest(std::move(thread)); | ||||
|     return parent->server->HandleSyncRequest(SharedFrom(thread)); | ||||
| } | ||||
|  | ||||
| } // namespace Kernel | ||||
|   | ||||
| @@ -19,6 +19,9 @@ class Thread; | ||||
|  | ||||
| class ClientSession final : public Object { | ||||
| public: | ||||
|     explicit ClientSession(KernelCore& kernel); | ||||
|     ~ClientSession() override; | ||||
|  | ||||
|     friend class ServerSession; | ||||
|  | ||||
|     std::string GetTypeName() const override { | ||||
| @@ -34,12 +37,9 @@ public: | ||||
|         return HANDLE_TYPE; | ||||
|     } | ||||
|  | ||||
|     ResultCode SendSyncRequest(SharedPtr<Thread> thread); | ||||
|     ResultCode SendSyncRequest(Thread* thread); | ||||
|  | ||||
| private: | ||||
|     explicit ClientSession(KernelCore& kernel); | ||||
|     ~ClientSession() override; | ||||
|  | ||||
|     /// The parent session, which links to the server endpoint. | ||||
|     std::shared_ptr<Session> parent; | ||||
|  | ||||
|   | ||||
| @@ -44,7 +44,7 @@ ResultCode HandleTable::SetSize(s32 handle_table_size) { | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
| ResultVal<Handle> HandleTable::Create(SharedPtr<Object> obj) { | ||||
| ResultVal<Handle> HandleTable::Create(std::shared_ptr<Object> obj) { | ||||
|     DEBUG_ASSERT(obj != nullptr); | ||||
|  | ||||
|     const u16 slot = next_free_slot; | ||||
| @@ -70,7 +70,7 @@ ResultVal<Handle> HandleTable::Create(SharedPtr<Object> obj) { | ||||
| } | ||||
|  | ||||
| ResultVal<Handle> HandleTable::Duplicate(Handle handle) { | ||||
|     SharedPtr<Object> object = GetGeneric(handle); | ||||
|     std::shared_ptr<Object> object = GetGeneric(handle); | ||||
|     if (object == nullptr) { | ||||
|         LOG_ERROR(Kernel, "Tried to duplicate invalid handle: {:08X}", handle); | ||||
|         return ERR_INVALID_HANDLE; | ||||
| @@ -99,11 +99,11 @@ bool HandleTable::IsValid(Handle handle) const { | ||||
|     return slot < table_size && objects[slot] != nullptr && generations[slot] == generation; | ||||
| } | ||||
|  | ||||
| SharedPtr<Object> HandleTable::GetGeneric(Handle handle) const { | ||||
| std::shared_ptr<Object> HandleTable::GetGeneric(Handle handle) const { | ||||
|     if (handle == CurrentThread) { | ||||
|         return GetCurrentThread(); | ||||
|         return SharedFrom(GetCurrentThread()); | ||||
|     } else if (handle == CurrentProcess) { | ||||
|         return Core::System::GetInstance().CurrentProcess(); | ||||
|         return SharedFrom(Core::System::GetInstance().CurrentProcess()); | ||||
|     } | ||||
|  | ||||
|     if (!IsValid(handle)) { | ||||
|   | ||||
| @@ -68,7 +68,7 @@ public: | ||||
|      * @return The created Handle or one of the following errors: | ||||
|      *           - `ERR_HANDLE_TABLE_FULL`: the maximum number of handles has been exceeded. | ||||
|      */ | ||||
|     ResultVal<Handle> Create(SharedPtr<Object> obj); | ||||
|     ResultVal<Handle> Create(std::shared_ptr<Object> obj); | ||||
|  | ||||
|     /** | ||||
|      * Returns a new handle that points to the same object as the passed in handle. | ||||
| @@ -92,7 +92,7 @@ public: | ||||
|      * Looks up a handle. | ||||
|      * @return Pointer to the looked-up object, or `nullptr` if the handle is not valid. | ||||
|      */ | ||||
|     SharedPtr<Object> GetGeneric(Handle handle) const; | ||||
|     std::shared_ptr<Object> GetGeneric(Handle handle) const; | ||||
|  | ||||
|     /** | ||||
|      * Looks up a handle while verifying its type. | ||||
| @@ -100,7 +100,7 @@ public: | ||||
|      *         type differs from the requested one. | ||||
|      */ | ||||
|     template <class T> | ||||
|     SharedPtr<T> Get(Handle handle) const { | ||||
|     std::shared_ptr<T> Get(Handle handle) const { | ||||
|         return DynamicObjectCast<T>(GetGeneric(handle)); | ||||
|     } | ||||
|  | ||||
| @@ -109,7 +109,7 @@ public: | ||||
|  | ||||
| private: | ||||
|     /// Stores the Object referenced by the handle or null if the slot is empty. | ||||
|     std::array<SharedPtr<Object>, MAX_COUNT> objects; | ||||
|     std::array<std::shared_ptr<Object>, MAX_COUNT> objects; | ||||
|  | ||||
|     /** | ||||
|      * The value of `next_generation` when the handle was created, used to check for validity. For | ||||
|   | ||||
| @@ -32,23 +32,25 @@ SessionRequestHandler::SessionRequestHandler() = default; | ||||
|  | ||||
| SessionRequestHandler::~SessionRequestHandler() = default; | ||||
|  | ||||
| void SessionRequestHandler::ClientConnected(SharedPtr<ServerSession> server_session) { | ||||
| void SessionRequestHandler::ClientConnected(std::shared_ptr<ServerSession> server_session) { | ||||
|     server_session->SetHleHandler(shared_from_this()); | ||||
|     connected_sessions.push_back(std::move(server_session)); | ||||
| } | ||||
|  | ||||
| void SessionRequestHandler::ClientDisconnected(const SharedPtr<ServerSession>& server_session) { | ||||
| void SessionRequestHandler::ClientDisconnected( | ||||
|     const std::shared_ptr<ServerSession>& server_session) { | ||||
|     server_session->SetHleHandler(nullptr); | ||||
|     boost::range::remove_erase(connected_sessions, server_session); | ||||
| } | ||||
|  | ||||
| SharedPtr<WritableEvent> HLERequestContext::SleepClientThread( | ||||
| std::shared_ptr<WritableEvent> HLERequestContext::SleepClientThread( | ||||
|     const std::string& reason, u64 timeout, WakeupCallback&& callback, | ||||
|     SharedPtr<WritableEvent> writable_event) { | ||||
|     std::shared_ptr<WritableEvent> writable_event) { | ||||
|     // Put the client thread to sleep until the wait event is signaled or the timeout expires. | ||||
|     thread->SetWakeupCallback([context = *this, callback]( | ||||
|                                   ThreadWakeupReason reason, SharedPtr<Thread> thread, | ||||
|                                   SharedPtr<WaitObject> object, std::size_t index) mutable -> bool { | ||||
|     thread->SetWakeupCallback([context = *this, callback](ThreadWakeupReason reason, | ||||
|                                                           std::shared_ptr<Thread> thread, | ||||
|                                                           std::shared_ptr<WaitObject> object, | ||||
|                                                           std::size_t index) mutable -> bool { | ||||
|         ASSERT(thread->GetStatus() == ThreadStatus::WaitHLEEvent); | ||||
|         callback(thread, context, reason); | ||||
|         context.WriteToOutgoingCommandBuffer(*thread); | ||||
| @@ -75,8 +77,8 @@ SharedPtr<WritableEvent> HLERequestContext::SleepClientThread( | ||||
|     return writable_event; | ||||
| } | ||||
|  | ||||
| HLERequestContext::HLERequestContext(SharedPtr<Kernel::ServerSession> server_session, | ||||
|                                      SharedPtr<Thread> thread) | ||||
| HLERequestContext::HLERequestContext(std::shared_ptr<Kernel::ServerSession> server_session, | ||||
|                                      std::shared_ptr<Thread> thread) | ||||
|     : server_session(std::move(server_session)), thread(std::move(thread)) { | ||||
|     cmd_buf[0] = 0; | ||||
| } | ||||
|   | ||||
| @@ -5,6 +5,7 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <array> | ||||
| #include <functional> | ||||
| #include <memory> | ||||
| #include <optional> | ||||
| #include <string> | ||||
| @@ -60,20 +61,20 @@ public: | ||||
|      * associated ServerSession alive for the duration of the connection. | ||||
|      * @param server_session Owning pointer to the ServerSession associated with the connection. | ||||
|      */ | ||||
|     void ClientConnected(SharedPtr<ServerSession> server_session); | ||||
|     void ClientConnected(std::shared_ptr<ServerSession> server_session); | ||||
|  | ||||
|     /** | ||||
|      * Signals that a client has just disconnected from this HLE handler and releases the | ||||
|      * associated ServerSession. | ||||
|      * @param server_session ServerSession associated with the connection. | ||||
|      */ | ||||
|     void ClientDisconnected(const SharedPtr<ServerSession>& server_session); | ||||
|     void ClientDisconnected(const std::shared_ptr<ServerSession>& server_session); | ||||
|  | ||||
| protected: | ||||
|     /// List of sessions that are connected to this handler. | ||||
|     /// A ServerSession whose server endpoint is an HLE implementation is kept alive by this list | ||||
|     /// for the duration of the connection. | ||||
|     std::vector<SharedPtr<ServerSession>> connected_sessions; | ||||
|     std::vector<std::shared_ptr<ServerSession>> connected_sessions; | ||||
| }; | ||||
|  | ||||
| /** | ||||
| @@ -97,7 +98,8 @@ protected: | ||||
|  */ | ||||
| class HLERequestContext { | ||||
| public: | ||||
|     explicit HLERequestContext(SharedPtr<ServerSession> session, SharedPtr<Thread> thread); | ||||
|     explicit HLERequestContext(std::shared_ptr<ServerSession> session, | ||||
|                                std::shared_ptr<Thread> thread); | ||||
|     ~HLERequestContext(); | ||||
|  | ||||
|     /// Returns a pointer to the IPC command buffer for this request. | ||||
| @@ -109,12 +111,12 @@ public: | ||||
|      * Returns the session through which this request was made. This can be used as a map key to | ||||
|      * access per-client data on services. | ||||
|      */ | ||||
|     const SharedPtr<Kernel::ServerSession>& Session() const { | ||||
|     const std::shared_ptr<Kernel::ServerSession>& Session() const { | ||||
|         return server_session; | ||||
|     } | ||||
|  | ||||
|     using WakeupCallback = std::function<void(SharedPtr<Thread> thread, HLERequestContext& context, | ||||
|                                               ThreadWakeupReason reason)>; | ||||
|     using WakeupCallback = std::function<void( | ||||
|         std::shared_ptr<Thread> thread, HLERequestContext& context, ThreadWakeupReason reason)>; | ||||
|  | ||||
|     /** | ||||
|      * Puts the specified guest thread to sleep until the returned event is signaled or until the | ||||
| @@ -129,9 +131,9 @@ public: | ||||
|      * created. | ||||
|      * @returns Event that when signaled will resume the thread and call the callback function. | ||||
|      */ | ||||
|     SharedPtr<WritableEvent> SleepClientThread(const std::string& reason, u64 timeout, | ||||
|                                                WakeupCallback&& callback, | ||||
|                                                SharedPtr<WritableEvent> writable_event = nullptr); | ||||
|     std::shared_ptr<WritableEvent> SleepClientThread( | ||||
|         const std::string& reason, u64 timeout, WakeupCallback&& callback, | ||||
|         std::shared_ptr<WritableEvent> writable_event = nullptr); | ||||
|  | ||||
|     /// Populates this context with data from the requesting process/thread. | ||||
|     ResultCode PopulateFromIncomingCommandBuffer(const HandleTable& handle_table, | ||||
| @@ -209,20 +211,20 @@ public: | ||||
|     std::size_t GetWriteBufferSize(int buffer_index = 0) const; | ||||
|  | ||||
|     template <typename T> | ||||
|     SharedPtr<T> GetCopyObject(std::size_t index) { | ||||
|     std::shared_ptr<T> GetCopyObject(std::size_t index) { | ||||
|         return DynamicObjectCast<T>(copy_objects.at(index)); | ||||
|     } | ||||
|  | ||||
|     template <typename T> | ||||
|     SharedPtr<T> GetMoveObject(std::size_t index) { | ||||
|     std::shared_ptr<T> GetMoveObject(std::size_t index) { | ||||
|         return DynamicObjectCast<T>(move_objects.at(index)); | ||||
|     } | ||||
|  | ||||
|     void AddMoveObject(SharedPtr<Object> object) { | ||||
|     void AddMoveObject(std::shared_ptr<Object> object) { | ||||
|         move_objects.emplace_back(std::move(object)); | ||||
|     } | ||||
|  | ||||
|     void AddCopyObject(SharedPtr<Object> object) { | ||||
|     void AddCopyObject(std::shared_ptr<Object> object) { | ||||
|         copy_objects.emplace_back(std::move(object)); | ||||
|     } | ||||
|  | ||||
| @@ -266,11 +268,11 @@ private: | ||||
|     void ParseCommandBuffer(const HandleTable& handle_table, u32_le* src_cmdbuf, bool incoming); | ||||
|  | ||||
|     std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf; | ||||
|     SharedPtr<Kernel::ServerSession> server_session; | ||||
|     SharedPtr<Thread> thread; | ||||
|     std::shared_ptr<Kernel::ServerSession> server_session; | ||||
|     std::shared_ptr<Thread> thread; | ||||
|     // TODO(yuriks): Check common usage of this and optimize size accordingly | ||||
|     boost::container::small_vector<SharedPtr<Object>, 8> move_objects; | ||||
|     boost::container::small_vector<SharedPtr<Object>, 8> copy_objects; | ||||
|     boost::container::small_vector<std::shared_ptr<Object>, 8> move_objects; | ||||
|     boost::container::small_vector<std::shared_ptr<Object>, 8> copy_objects; | ||||
|     boost::container::small_vector<std::shared_ptr<SessionRequestHandler>, 8> domain_objects; | ||||
|  | ||||
|     std::optional<IPC::CommandHeader> command_header; | ||||
|   | ||||
| @@ -40,7 +40,7 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] s64 cycles_ | ||||
|     // Lock the global kernel mutex when we enter the kernel HLE. | ||||
|     std::lock_guard lock{HLE::g_hle_lock}; | ||||
|  | ||||
|     SharedPtr<Thread> thread = | ||||
|     std::shared_ptr<Thread> thread = | ||||
|         system.Kernel().RetrieveThreadFromWakeupCallbackHandleTable(proper_handle); | ||||
|     if (thread == nullptr) { | ||||
|         LOG_CRITICAL(Kernel, "Callback fired for invalid thread {:08X}", proper_handle); | ||||
| @@ -53,7 +53,7 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] s64 cycles_ | ||||
|         thread->GetStatus() == ThreadStatus::WaitHLEEvent) { | ||||
|         // Remove the thread from each of its waiting objects' waitlists | ||||
|         for (const auto& object : thread->GetWaitObjects()) { | ||||
|             object->RemoveWaitingThread(thread.get()); | ||||
|             object->RemoveWaitingThread(thread); | ||||
|         } | ||||
|         thread->ClearWaitObjects(); | ||||
|  | ||||
| @@ -160,11 +160,11 @@ struct KernelCore::Impl { | ||||
|     std::atomic<u64> next_thread_id{1}; | ||||
|  | ||||
|     // Lists all processes that exist in the current session. | ||||
|     std::vector<SharedPtr<Process>> process_list; | ||||
|     std::vector<std::shared_ptr<Process>> process_list; | ||||
|     Process* current_process = nullptr; | ||||
|     Kernel::GlobalScheduler global_scheduler; | ||||
|  | ||||
|     SharedPtr<ResourceLimit> system_resource_limit; | ||||
|     std::shared_ptr<ResourceLimit> system_resource_limit; | ||||
|  | ||||
|     Core::Timing::EventType* thread_wakeup_event_type = nullptr; | ||||
|     Core::Timing::EventType* preemption_event = nullptr; | ||||
| @@ -193,15 +193,16 @@ void KernelCore::Shutdown() { | ||||
|     impl->Shutdown(); | ||||
| } | ||||
|  | ||||
| SharedPtr<ResourceLimit> KernelCore::GetSystemResourceLimit() const { | ||||
| std::shared_ptr<ResourceLimit> KernelCore::GetSystemResourceLimit() const { | ||||
|     return impl->system_resource_limit; | ||||
| } | ||||
|  | ||||
| SharedPtr<Thread> KernelCore::RetrieveThreadFromWakeupCallbackHandleTable(Handle handle) const { | ||||
| std::shared_ptr<Thread> KernelCore::RetrieveThreadFromWakeupCallbackHandleTable( | ||||
|     Handle handle) const { | ||||
|     return impl->thread_wakeup_callback_handle_table.Get<Thread>(handle); | ||||
| } | ||||
|  | ||||
| void KernelCore::AppendNewProcess(SharedPtr<Process> process) { | ||||
| void KernelCore::AppendNewProcess(std::shared_ptr<Process> process) { | ||||
|     impl->process_list.push_back(std::move(process)); | ||||
| } | ||||
|  | ||||
| @@ -223,7 +224,7 @@ const Process* KernelCore::CurrentProcess() const { | ||||
|     return impl->current_process; | ||||
| } | ||||
|  | ||||
| const std::vector<SharedPtr<Process>>& KernelCore::GetProcessList() const { | ||||
| const std::vector<std::shared_ptr<Process>>& KernelCore::GetProcessList() const { | ||||
|     return impl->process_list; | ||||
| } | ||||
|  | ||||
| @@ -235,7 +236,7 @@ const Kernel::GlobalScheduler& KernelCore::GlobalScheduler() const { | ||||
|     return impl->global_scheduler; | ||||
| } | ||||
|  | ||||
| void KernelCore::AddNamedPort(std::string name, SharedPtr<ClientPort> port) { | ||||
| void KernelCore::AddNamedPort(std::string name, std::shared_ptr<ClientPort> port) { | ||||
|     impl->named_ports.emplace(std::move(name), std::move(port)); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -6,6 +6,7 @@ | ||||
|  | ||||
| #include <string> | ||||
| #include <unordered_map> | ||||
| #include <vector> | ||||
| #include "core/hle/kernel/object.h" | ||||
|  | ||||
| namespace Core { | ||||
| @@ -30,7 +31,7 @@ class Thread; | ||||
| /// Represents a single instance of the kernel. | ||||
| class KernelCore { | ||||
| private: | ||||
|     using NamedPortTable = std::unordered_map<std::string, SharedPtr<ClientPort>>; | ||||
|     using NamedPortTable = std::unordered_map<std::string, std::shared_ptr<ClientPort>>; | ||||
|  | ||||
| public: | ||||
|     /// Constructs an instance of the kernel using the given System | ||||
| @@ -56,13 +57,13 @@ public: | ||||
|     void Shutdown(); | ||||
|  | ||||
|     /// Retrieves a shared pointer to the system resource limit instance. | ||||
|     SharedPtr<ResourceLimit> GetSystemResourceLimit() const; | ||||
|     std::shared_ptr<ResourceLimit> GetSystemResourceLimit() const; | ||||
|  | ||||
|     /// Retrieves a shared pointer to a Thread instance within the thread wakeup handle table. | ||||
|     SharedPtr<Thread> RetrieveThreadFromWakeupCallbackHandleTable(Handle handle) const; | ||||
|     std::shared_ptr<Thread> RetrieveThreadFromWakeupCallbackHandleTable(Handle handle) const; | ||||
|  | ||||
|     /// Adds the given shared pointer to an internal list of active processes. | ||||
|     void AppendNewProcess(SharedPtr<Process> process); | ||||
|     void AppendNewProcess(std::shared_ptr<Process> process); | ||||
|  | ||||
|     /// Makes the given process the new current process. | ||||
|     void MakeCurrentProcess(Process* process); | ||||
| @@ -74,7 +75,7 @@ public: | ||||
|     const Process* CurrentProcess() const; | ||||
|  | ||||
|     /// Retrieves the list of processes. | ||||
|     const std::vector<SharedPtr<Process>>& GetProcessList() const; | ||||
|     const std::vector<std::shared_ptr<Process>>& GetProcessList() const; | ||||
|  | ||||
|     /// Gets the sole instance of the global scheduler | ||||
|     Kernel::GlobalScheduler& GlobalScheduler(); | ||||
| @@ -83,7 +84,7 @@ public: | ||||
|     const Kernel::GlobalScheduler& GlobalScheduler() const; | ||||
|  | ||||
|     /// Adds a port to the named port table | ||||
|     void AddNamedPort(std::string name, SharedPtr<ClientPort> port); | ||||
|     void AddNamedPort(std::string name, std::shared_ptr<ClientPort> port); | ||||
|  | ||||
|     /// Finds a port within the named port table with the given name. | ||||
|     NamedPortTable::iterator FindNamedPort(const std::string& name); | ||||
|   | ||||
| @@ -22,10 +22,10 @@ namespace Kernel { | ||||
|  | ||||
| /// Returns the number of threads that are waiting for a mutex, and the highest priority one among | ||||
| /// those. | ||||
| static std::pair<SharedPtr<Thread>, u32> GetHighestPriorityMutexWaitingThread( | ||||
|     const SharedPtr<Thread>& current_thread, VAddr mutex_addr) { | ||||
| static std::pair<std::shared_ptr<Thread>, u32> GetHighestPriorityMutexWaitingThread( | ||||
|     const std::shared_ptr<Thread>& current_thread, VAddr mutex_addr) { | ||||
|  | ||||
|     SharedPtr<Thread> highest_priority_thread; | ||||
|     std::shared_ptr<Thread> highest_priority_thread; | ||||
|     u32 num_waiters = 0; | ||||
|  | ||||
|     for (const auto& thread : current_thread->GetMutexWaitingThreads()) { | ||||
| @@ -45,14 +45,14 @@ static std::pair<SharedPtr<Thread>, u32> GetHighestPriorityMutexWaitingThread( | ||||
| } | ||||
|  | ||||
| /// Update the mutex owner field of all threads waiting on the mutex to point to the new owner. | ||||
| static void TransferMutexOwnership(VAddr mutex_addr, SharedPtr<Thread> current_thread, | ||||
|                                    SharedPtr<Thread> new_owner) { | ||||
| static void TransferMutexOwnership(VAddr mutex_addr, std::shared_ptr<Thread> current_thread, | ||||
|                                    std::shared_ptr<Thread> new_owner) { | ||||
|     const auto threads = current_thread->GetMutexWaitingThreads(); | ||||
|     for (const auto& thread : threads) { | ||||
|         if (thread->GetMutexWaitAddress() != mutex_addr) | ||||
|             continue; | ||||
|  | ||||
|         ASSERT(thread->GetLockOwner() == current_thread); | ||||
|         ASSERT(thread->GetLockOwner() == current_thread.get()); | ||||
|         current_thread->RemoveMutexWaiter(thread); | ||||
|         if (new_owner != thread) | ||||
|             new_owner->AddMutexWaiter(thread); | ||||
| @@ -70,9 +70,10 @@ ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle, | ||||
|     } | ||||
|  | ||||
|     const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | ||||
|     Thread* const current_thread = system.CurrentScheduler().GetCurrentThread(); | ||||
|     SharedPtr<Thread> holding_thread = handle_table.Get<Thread>(holding_thread_handle); | ||||
|     SharedPtr<Thread> requesting_thread = handle_table.Get<Thread>(requesting_thread_handle); | ||||
|     std::shared_ptr<Thread> current_thread = | ||||
|         SharedFrom(system.CurrentScheduler().GetCurrentThread()); | ||||
|     std::shared_ptr<Thread> holding_thread = handle_table.Get<Thread>(holding_thread_handle); | ||||
|     std::shared_ptr<Thread> requesting_thread = handle_table.Get<Thread>(requesting_thread_handle); | ||||
|  | ||||
|     // TODO(Subv): It is currently unknown if it is possible to lock a mutex in behalf of another | ||||
|     // thread. | ||||
| @@ -110,7 +111,8 @@ ResultCode Mutex::Release(VAddr address) { | ||||
|         return ERR_INVALID_ADDRESS; | ||||
|     } | ||||
|  | ||||
|     auto* const current_thread = system.CurrentScheduler().GetCurrentThread(); | ||||
|     std::shared_ptr<Thread> current_thread = | ||||
|         SharedFrom(system.CurrentScheduler().GetCurrentThread()); | ||||
|     auto [thread, num_waiters] = GetHighestPriorityMutexWaitingThread(current_thread, address); | ||||
|  | ||||
|     // There are no more threads waiting for the mutex, release it completely. | ||||
|   | ||||
| @@ -5,10 +5,9 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <atomic> | ||||
| #include <memory> | ||||
| #include <string> | ||||
|  | ||||
| #include <boost/smart_ptr/intrusive_ptr.hpp> | ||||
|  | ||||
| #include "common/common_types.h" | ||||
|  | ||||
| namespace Kernel { | ||||
| @@ -32,7 +31,7 @@ enum class HandleType : u32 { | ||||
|     ServerSession, | ||||
| }; | ||||
|  | ||||
| class Object : NonCopyable { | ||||
| class Object : NonCopyable, public std::enable_shared_from_this<Object> { | ||||
| public: | ||||
|     explicit Object(KernelCore& kernel); | ||||
|     virtual ~Object(); | ||||
| @@ -61,35 +60,24 @@ protected: | ||||
|     KernelCore& kernel; | ||||
|  | ||||
| private: | ||||
|     friend void intrusive_ptr_add_ref(Object*); | ||||
|     friend void intrusive_ptr_release(Object*); | ||||
|  | ||||
|     std::atomic<u32> ref_count{0}; | ||||
|     std::atomic<u32> object_id{0}; | ||||
| }; | ||||
|  | ||||
| // Special functions used by boost::instrusive_ptr to do automatic ref-counting | ||||
| inline void intrusive_ptr_add_ref(Object* object) { | ||||
|     object->ref_count.fetch_add(1, std::memory_order_relaxed); | ||||
| } | ||||
|  | ||||
| inline void intrusive_ptr_release(Object* object) { | ||||
|     if (object->ref_count.fetch_sub(1, std::memory_order_acq_rel) == 1) { | ||||
|         delete object; | ||||
|     } | ||||
| } | ||||
|  | ||||
| template <typename T> | ||||
| using SharedPtr = boost::intrusive_ptr<T>; | ||||
| std::shared_ptr<T> SharedFrom(T* raw) { | ||||
|     if (raw == nullptr) | ||||
|         return nullptr; | ||||
|     return std::static_pointer_cast<T>(raw->shared_from_this()); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Attempts to downcast the given Object pointer to a pointer to T. | ||||
|  * @return Derived pointer to the object, or `nullptr` if `object` isn't of type T. | ||||
|  */ | ||||
| template <typename T> | ||||
| inline SharedPtr<T> DynamicObjectCast(SharedPtr<Object> object) { | ||||
| inline std::shared_ptr<T> DynamicObjectCast(std::shared_ptr<Object> object) { | ||||
|     if (object != nullptr && object->GetHandleType() == T::HANDLE_TYPE) { | ||||
|         return boost::static_pointer_cast<T>(object); | ||||
|         return std::static_pointer_cast<T>(object); | ||||
|     } | ||||
|     return nullptr; | ||||
| } | ||||
|   | ||||
| @@ -38,7 +38,7 @@ void SetupMainThread(Process& owner_process, KernelCore& kernel, u32 priority) { | ||||
|     auto thread_res = Thread::Create(kernel, "main", entry_point, priority, 0, | ||||
|                                      owner_process.GetIdealCore(), stack_top, owner_process); | ||||
|  | ||||
|     SharedPtr<Thread> thread = std::move(thread_res).Unwrap(); | ||||
|     std::shared_ptr<Thread> thread = std::move(thread_res).Unwrap(); | ||||
|  | ||||
|     // Register 1 must be a handle to the main thread | ||||
|     const Handle thread_handle = owner_process.GetHandleTable().Create(thread).Unwrap(); | ||||
| @@ -100,10 +100,10 @@ private: | ||||
|     std::bitset<num_slot_entries> is_slot_used; | ||||
| }; | ||||
|  | ||||
| SharedPtr<Process> Process::Create(Core::System& system, std::string name, ProcessType type) { | ||||
| std::shared_ptr<Process> Process::Create(Core::System& system, std::string name, ProcessType type) { | ||||
|     auto& kernel = system.Kernel(); | ||||
|  | ||||
|     SharedPtr<Process> process(new Process(system)); | ||||
|     std::shared_ptr<Process> process = std::make_shared<Process>(system); | ||||
|     process->name = std::move(name); | ||||
|     process->resource_limit = kernel.GetSystemResourceLimit(); | ||||
|     process->status = ProcessStatus::Created; | ||||
| @@ -121,7 +121,7 @@ SharedPtr<Process> Process::Create(Core::System& system, std::string name, Proce | ||||
|     return process; | ||||
| } | ||||
|  | ||||
| SharedPtr<ResourceLimit> Process::GetResourceLimit() const { | ||||
| std::shared_ptr<ResourceLimit> Process::GetResourceLimit() const { | ||||
|     return resource_limit; | ||||
| } | ||||
|  | ||||
| @@ -142,12 +142,12 @@ u64 Process::GetTotalPhysicalMemoryUsedWithoutSystemResource() const { | ||||
|     return GetTotalPhysicalMemoryUsed() - GetSystemResourceUsage(); | ||||
| } | ||||
|  | ||||
| void Process::InsertConditionVariableThread(SharedPtr<Thread> thread) { | ||||
| void Process::InsertConditionVariableThread(std::shared_ptr<Thread> thread) { | ||||
|     VAddr cond_var_addr = thread->GetCondVarWaitAddress(); | ||||
|     std::list<SharedPtr<Thread>>& thread_list = cond_var_threads[cond_var_addr]; | ||||
|     std::list<std::shared_ptr<Thread>>& thread_list = cond_var_threads[cond_var_addr]; | ||||
|     auto it = thread_list.begin(); | ||||
|     while (it != thread_list.end()) { | ||||
|         const SharedPtr<Thread> current_thread = *it; | ||||
|         const std::shared_ptr<Thread> current_thread = *it; | ||||
|         if (current_thread->GetPriority() > thread->GetPriority()) { | ||||
|             thread_list.insert(it, thread); | ||||
|             return; | ||||
| @@ -157,12 +157,12 @@ void Process::InsertConditionVariableThread(SharedPtr<Thread> thread) { | ||||
|     thread_list.push_back(thread); | ||||
| } | ||||
|  | ||||
| void Process::RemoveConditionVariableThread(SharedPtr<Thread> thread) { | ||||
| void Process::RemoveConditionVariableThread(std::shared_ptr<Thread> thread) { | ||||
|     VAddr cond_var_addr = thread->GetCondVarWaitAddress(); | ||||
|     std::list<SharedPtr<Thread>>& thread_list = cond_var_threads[cond_var_addr]; | ||||
|     std::list<std::shared_ptr<Thread>>& thread_list = cond_var_threads[cond_var_addr]; | ||||
|     auto it = thread_list.begin(); | ||||
|     while (it != thread_list.end()) { | ||||
|         const SharedPtr<Thread> current_thread = *it; | ||||
|         const std::shared_ptr<Thread> current_thread = *it; | ||||
|         if (current_thread.get() == thread.get()) { | ||||
|             thread_list.erase(it); | ||||
|             return; | ||||
| @@ -172,12 +172,13 @@ void Process::RemoveConditionVariableThread(SharedPtr<Thread> thread) { | ||||
|     UNREACHABLE(); | ||||
| } | ||||
|  | ||||
| std::vector<SharedPtr<Thread>> Process::GetConditionVariableThreads(const VAddr cond_var_addr) { | ||||
|     std::vector<SharedPtr<Thread>> result{}; | ||||
|     std::list<SharedPtr<Thread>>& thread_list = cond_var_threads[cond_var_addr]; | ||||
| std::vector<std::shared_ptr<Thread>> Process::GetConditionVariableThreads( | ||||
|     const VAddr cond_var_addr) { | ||||
|     std::vector<std::shared_ptr<Thread>> result{}; | ||||
|     std::list<std::shared_ptr<Thread>>& thread_list = cond_var_threads[cond_var_addr]; | ||||
|     auto it = thread_list.begin(); | ||||
|     while (it != thread_list.end()) { | ||||
|         SharedPtr<Thread> current_thread = *it; | ||||
|         std::shared_ptr<Thread> current_thread = *it; | ||||
|         result.push_back(current_thread); | ||||
|         ++it; | ||||
|     } | ||||
| @@ -239,12 +240,12 @@ void Process::Run(s32 main_thread_priority, u64 stack_size) { | ||||
| void Process::PrepareForTermination() { | ||||
|     ChangeStatus(ProcessStatus::Exiting); | ||||
|  | ||||
|     const auto stop_threads = [this](const std::vector<SharedPtr<Thread>>& thread_list) { | ||||
|     const auto stop_threads = [this](const std::vector<std::shared_ptr<Thread>>& thread_list) { | ||||
|         for (auto& thread : thread_list) { | ||||
|             if (thread->GetOwnerProcess() != this) | ||||
|                 continue; | ||||
|  | ||||
|             if (thread == system.CurrentScheduler().GetCurrentThread()) | ||||
|             if (thread.get() == system.CurrentScheduler().GetCurrentThread()) | ||||
|                 continue; | ||||
|  | ||||
|             // TODO(Subv): When are the other running/ready threads terminated? | ||||
|   | ||||
| @@ -62,6 +62,9 @@ enum class ProcessStatus { | ||||
|  | ||||
| class Process final : public WaitObject { | ||||
| public: | ||||
|     explicit Process(Core::System& system); | ||||
|     ~Process() override; | ||||
|  | ||||
|     enum : u64 { | ||||
|         /// Lowest allowed process ID for a kernel initial process. | ||||
|         InitialKIPIDMin = 1, | ||||
| @@ -82,7 +85,8 @@ public: | ||||
|  | ||||
|     static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4; | ||||
|  | ||||
|     static SharedPtr<Process> Create(Core::System& system, std::string name, ProcessType type); | ||||
|     static std::shared_ptr<Process> Create(Core::System& system, std::string name, | ||||
|                                            ProcessType type); | ||||
|  | ||||
|     std::string GetTypeName() const override { | ||||
|         return "Process"; | ||||
| @@ -157,7 +161,7 @@ public: | ||||
|     } | ||||
|  | ||||
|     /// Gets the resource limit descriptor for this process | ||||
|     SharedPtr<ResourceLimit> GetResourceLimit() const; | ||||
|     std::shared_ptr<ResourceLimit> GetResourceLimit() const; | ||||
|  | ||||
|     /// Gets the ideal CPU core ID for this process | ||||
|     u8 GetIdealCore() const { | ||||
| @@ -234,13 +238,13 @@ public: | ||||
|     } | ||||
|  | ||||
|     /// Insert a thread into the condition variable wait container | ||||
|     void InsertConditionVariableThread(SharedPtr<Thread> thread); | ||||
|     void InsertConditionVariableThread(std::shared_ptr<Thread> thread); | ||||
|  | ||||
|     /// Remove a thread from the condition variable wait container | ||||
|     void RemoveConditionVariableThread(SharedPtr<Thread> thread); | ||||
|     void RemoveConditionVariableThread(std::shared_ptr<Thread> thread); | ||||
|  | ||||
|     /// Obtain all condition variable threads waiting for some address | ||||
|     std::vector<SharedPtr<Thread>> GetConditionVariableThreads(VAddr cond_var_addr); | ||||
|     std::vector<std::shared_ptr<Thread>> GetConditionVariableThreads(VAddr cond_var_addr); | ||||
|  | ||||
|     /// Registers a thread as being created under this process, | ||||
|     /// adding it to this process' thread list. | ||||
| @@ -297,9 +301,6 @@ public: | ||||
|     void FreeTLSRegion(VAddr tls_address); | ||||
|  | ||||
| private: | ||||
|     explicit Process(Core::System& system); | ||||
|     ~Process() override; | ||||
|  | ||||
|     /// Checks if the specified thread should wait until this process is available. | ||||
|     bool ShouldWait(const Thread* thread) const override; | ||||
|  | ||||
| @@ -338,7 +339,7 @@ private: | ||||
|     u32 system_resource_size = 0; | ||||
|  | ||||
|     /// Resource limit descriptor for this process | ||||
|     SharedPtr<ResourceLimit> resource_limit; | ||||
|     std::shared_ptr<ResourceLimit> resource_limit; | ||||
|  | ||||
|     /// The ideal CPU core for this process, threads are scheduled on this core by default. | ||||
|     u8 ideal_core = 0; | ||||
| @@ -386,7 +387,7 @@ private: | ||||
|     std::list<const Thread*> thread_list; | ||||
|  | ||||
|     /// List of threads waiting for a condition variable | ||||
|     std::unordered_map<VAddr, std::list<SharedPtr<Thread>>> cond_var_threads; | ||||
|     std::unordered_map<VAddr, std::list<std::shared_ptr<Thread>>> cond_var_threads; | ||||
|  | ||||
|     /// System context | ||||
|     Core::System& system; | ||||
|   | ||||
| @@ -16,8 +16,8 @@ constexpr std::size_t ResourceTypeToIndex(ResourceType type) { | ||||
| ResourceLimit::ResourceLimit(KernelCore& kernel) : Object{kernel} {} | ||||
| ResourceLimit::~ResourceLimit() = default; | ||||
|  | ||||
| SharedPtr<ResourceLimit> ResourceLimit::Create(KernelCore& kernel) { | ||||
|     return new ResourceLimit(kernel); | ||||
| std::shared_ptr<ResourceLimit> ResourceLimit::Create(KernelCore& kernel) { | ||||
|     return std::make_shared<ResourceLimit>(kernel); | ||||
| } | ||||
|  | ||||
| s64 ResourceLimit::GetCurrentResourceValue(ResourceType resource) const { | ||||
|   | ||||
| @@ -31,8 +31,11 @@ constexpr bool IsValidResourceType(ResourceType type) { | ||||
|  | ||||
| class ResourceLimit final : public Object { | ||||
| public: | ||||
|     explicit ResourceLimit(KernelCore& kernel); | ||||
|     ~ResourceLimit() override; | ||||
|  | ||||
|     /// Creates a resource limit object. | ||||
|     static SharedPtr<ResourceLimit> Create(KernelCore& kernel); | ||||
|     static std::shared_ptr<ResourceLimit> Create(KernelCore& kernel); | ||||
|  | ||||
|     std::string GetTypeName() const override { | ||||
|         return "ResourceLimit"; | ||||
| @@ -76,9 +79,6 @@ public: | ||||
|     ResultCode SetLimitValue(ResourceType resource, s64 value); | ||||
|  | ||||
| private: | ||||
|     explicit ResourceLimit(KernelCore& kernel); | ||||
|     ~ResourceLimit() override; | ||||
|  | ||||
|     // TODO(Subv): Increment resource limit current values in their respective Kernel::T::Create | ||||
|     // functions | ||||
|     // | ||||
|   | ||||
| @@ -26,11 +26,11 @@ GlobalScheduler::GlobalScheduler(Core::System& system) : system{system} {} | ||||
|  | ||||
| GlobalScheduler::~GlobalScheduler() = default; | ||||
|  | ||||
| void GlobalScheduler::AddThread(SharedPtr<Thread> thread) { | ||||
| void GlobalScheduler::AddThread(std::shared_ptr<Thread> thread) { | ||||
|     thread_list.push_back(std::move(thread)); | ||||
| } | ||||
|  | ||||
| void GlobalScheduler::RemoveThread(const Thread* thread) { | ||||
| void GlobalScheduler::RemoveThread(std::shared_ptr<Thread> thread) { | ||||
|     thread_list.erase(std::remove(thread_list.begin(), thread_list.end(), thread), | ||||
|                       thread_list.end()); | ||||
| } | ||||
| @@ -42,11 +42,11 @@ void GlobalScheduler::UnloadThread(std::size_t core) { | ||||
|  | ||||
| void GlobalScheduler::SelectThread(std::size_t core) { | ||||
|     const auto update_thread = [](Thread* thread, Scheduler& sched) { | ||||
|         if (thread != sched.selected_thread) { | ||||
|         if (thread != sched.selected_thread.get()) { | ||||
|             if (thread == nullptr) { | ||||
|                 ++sched.idle_selection_count; | ||||
|             } | ||||
|             sched.selected_thread = thread; | ||||
|             sched.selected_thread = SharedFrom(thread); | ||||
|         } | ||||
|         sched.is_context_switch_pending = sched.selected_thread != sched.current_thread; | ||||
|         std::atomic_thread_fence(std::memory_order_seq_cst); | ||||
| @@ -446,7 +446,7 @@ void Scheduler::SwitchContext() { | ||||
|  | ||||
|         // Cancel any outstanding wakeup events for this thread | ||||
|         new_thread->CancelWakeupTimer(); | ||||
|         current_thread = new_thread; | ||||
|         current_thread = SharedFrom(new_thread); | ||||
|         new_thread->SetStatus(ThreadStatus::Running); | ||||
|         new_thread->SetIsRunning(true); | ||||
|  | ||||
|   | ||||
| @@ -28,13 +28,13 @@ public: | ||||
|     ~GlobalScheduler(); | ||||
|  | ||||
|     /// Adds a new thread to the scheduler | ||||
|     void AddThread(SharedPtr<Thread> thread); | ||||
|     void AddThread(std::shared_ptr<Thread> thread); | ||||
|  | ||||
|     /// Removes a thread from the scheduler | ||||
|     void RemoveThread(const Thread* thread); | ||||
|     void RemoveThread(std::shared_ptr<Thread> thread); | ||||
|  | ||||
|     /// Returns a list of all threads managed by the scheduler | ||||
|     const std::vector<SharedPtr<Thread>>& GetThreadList() const { | ||||
|     const std::vector<std::shared_ptr<Thread>>& GetThreadList() const { | ||||
|         return thread_list; | ||||
|     } | ||||
|  | ||||
| @@ -157,7 +157,7 @@ private: | ||||
|     std::array<u32, NUM_CPU_CORES> preemption_priorities = {59, 59, 59, 62}; | ||||
|  | ||||
|     /// Lists all thread ids that aren't deleted/etc. | ||||
|     std::vector<SharedPtr<Thread>> thread_list; | ||||
|     std::vector<std::shared_ptr<Thread>> thread_list; | ||||
|     Core::System& system; | ||||
| }; | ||||
|  | ||||
| @@ -213,8 +213,8 @@ private: | ||||
|      */ | ||||
|     void UpdateLastContextSwitchTime(Thread* thread, Process* process); | ||||
|  | ||||
|     SharedPtr<Thread> current_thread = nullptr; | ||||
|     SharedPtr<Thread> selected_thread = nullptr; | ||||
|     std::shared_ptr<Thread> current_thread = nullptr; | ||||
|     std::shared_ptr<Thread> selected_thread = nullptr; | ||||
|  | ||||
|     Core::System& system; | ||||
|     Core::ARM_Interface& cpu_core; | ||||
|   | ||||
| @@ -16,7 +16,7 @@ namespace Kernel { | ||||
| ServerPort::ServerPort(KernelCore& kernel) : WaitObject{kernel} {} | ||||
| ServerPort::~ServerPort() = default; | ||||
|  | ||||
| ResultVal<SharedPtr<ServerSession>> ServerPort::Accept() { | ||||
| ResultVal<std::shared_ptr<ServerSession>> ServerPort::Accept() { | ||||
|     if (pending_sessions.empty()) { | ||||
|         return ERR_NOT_FOUND; | ||||
|     } | ||||
| @@ -26,7 +26,7 @@ ResultVal<SharedPtr<ServerSession>> ServerPort::Accept() { | ||||
|     return MakeResult(std::move(session)); | ||||
| } | ||||
|  | ||||
| void ServerPort::AppendPendingSession(SharedPtr<ServerSession> pending_session) { | ||||
| void ServerPort::AppendPendingSession(std::shared_ptr<ServerSession> pending_session) { | ||||
|     pending_sessions.push_back(std::move(pending_session)); | ||||
| } | ||||
|  | ||||
| @@ -41,8 +41,8 @@ void ServerPort::Acquire(Thread* thread) { | ||||
|  | ||||
| ServerPort::PortPair ServerPort::CreatePortPair(KernelCore& kernel, u32 max_sessions, | ||||
|                                                 std::string name) { | ||||
|     SharedPtr<ServerPort> server_port(new ServerPort(kernel)); | ||||
|     SharedPtr<ClientPort> client_port(new ClientPort(kernel)); | ||||
|     std::shared_ptr<ServerPort> server_port = std::make_shared<ServerPort>(kernel); | ||||
|     std::shared_ptr<ClientPort> client_port = std::make_shared<ClientPort>(kernel); | ||||
|  | ||||
|     server_port->name = name + "_Server"; | ||||
|     client_port->name = name + "_Client"; | ||||
|   | ||||
| @@ -22,8 +22,11 @@ class SessionRequestHandler; | ||||
|  | ||||
| class ServerPort final : public WaitObject { | ||||
| public: | ||||
|     explicit ServerPort(KernelCore& kernel); | ||||
|     ~ServerPort() override; | ||||
|  | ||||
|     using HLEHandler = std::shared_ptr<SessionRequestHandler>; | ||||
|     using PortPair = std::pair<SharedPtr<ServerPort>, SharedPtr<ClientPort>>; | ||||
|     using PortPair = std::pair<std::shared_ptr<ServerPort>, std::shared_ptr<ClientPort>>; | ||||
|  | ||||
|     /** | ||||
|      * Creates a pair of ServerPort and an associated ClientPort. | ||||
| @@ -52,7 +55,7 @@ public: | ||||
|      * Accepts a pending incoming connection on this port. If there are no pending sessions, will | ||||
|      * return ERR_NO_PENDING_SESSIONS. | ||||
|      */ | ||||
|     ResultVal<SharedPtr<ServerSession>> Accept(); | ||||
|     ResultVal<std::shared_ptr<ServerSession>> Accept(); | ||||
|  | ||||
|     /// Whether or not this server port has an HLE handler available. | ||||
|     bool HasHLEHandler() const { | ||||
| @@ -74,17 +77,14 @@ public: | ||||
|  | ||||
|     /// Appends a ServerSession to the collection of ServerSessions | ||||
|     /// waiting to be accepted by this port. | ||||
|     void AppendPendingSession(SharedPtr<ServerSession> pending_session); | ||||
|     void AppendPendingSession(std::shared_ptr<ServerSession> pending_session); | ||||
|  | ||||
|     bool ShouldWait(const Thread* thread) const override; | ||||
|     void Acquire(Thread* thread) override; | ||||
|  | ||||
| private: | ||||
|     explicit ServerPort(KernelCore& kernel); | ||||
|     ~ServerPort() override; | ||||
|  | ||||
|     /// ServerSessions waiting to be accepted by the port | ||||
|     std::vector<SharedPtr<ServerSession>> pending_sessions; | ||||
|     std::vector<std::shared_ptr<ServerSession>> pending_sessions; | ||||
|  | ||||
|     /// This session's HLE request handler template (optional) | ||||
|     /// ServerSessions created from this port inherit a reference to this handler. | ||||
|   | ||||
| @@ -35,8 +35,9 @@ ServerSession::~ServerSession() { | ||||
|     parent->server = nullptr; | ||||
| } | ||||
|  | ||||
| ResultVal<SharedPtr<ServerSession>> ServerSession::Create(KernelCore& kernel, std::string name) { | ||||
|     SharedPtr<ServerSession> server_session(new ServerSession(kernel)); | ||||
| ResultVal<std::shared_ptr<ServerSession>> ServerSession::Create(KernelCore& kernel, | ||||
|                                                                 std::string name) { | ||||
|     std::shared_ptr<ServerSession> server_session = std::make_shared<ServerSession>(kernel); | ||||
|  | ||||
|     server_session->name = std::move(name); | ||||
|     server_session->parent = nullptr; | ||||
| @@ -69,7 +70,7 @@ void ServerSession::ClientDisconnected() { | ||||
|     if (handler) { | ||||
|         // Note that after this returns, this server session's hle_handler is | ||||
|         // invalidated (set to null). | ||||
|         handler->ClientDisconnected(this); | ||||
|         handler->ClientDisconnected(SharedFrom(this)); | ||||
|     } | ||||
|  | ||||
|     // Clean up the list of client threads with pending requests, they are unneeded now that the | ||||
| @@ -126,11 +127,11 @@ ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& con | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
| ResultCode ServerSession::HandleSyncRequest(SharedPtr<Thread> thread) { | ||||
| ResultCode ServerSession::HandleSyncRequest(std::shared_ptr<Thread> thread) { | ||||
|     // The ServerSession received a sync request, this means that there's new data available | ||||
|     // from its ClientSession, so wake up any threads that may be waiting on a svcReplyAndReceive or | ||||
|     // similar. | ||||
|     Kernel::HLERequestContext context(this, thread); | ||||
|     Kernel::HLERequestContext context(SharedFrom(this), thread); | ||||
|     u32* cmd_buf = (u32*)Memory::GetPointer(thread->GetTLSAddress()); | ||||
|     context.PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf); | ||||
|  | ||||
| @@ -186,9 +187,9 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr<Thread> thread) { | ||||
|  | ||||
| ServerSession::SessionPair ServerSession::CreateSessionPair(KernelCore& kernel, | ||||
|                                                             const std::string& name, | ||||
|                                                             SharedPtr<ClientPort> port) { | ||||
|                                                             std::shared_ptr<ClientPort> port) { | ||||
|     auto server_session = ServerSession::Create(kernel, name + "_Server").Unwrap(); | ||||
|     SharedPtr<ClientSession> client_session(new ClientSession(kernel)); | ||||
|     std::shared_ptr<ClientSession> client_session = std::make_shared<ClientSession>(kernel); | ||||
|     client_session->name = name + "_Client"; | ||||
|  | ||||
|     std::shared_ptr<Session> parent(new Session); | ||||
|   | ||||
| @@ -38,6 +38,9 @@ class Thread; | ||||
|  */ | ||||
| class ServerSession final : public WaitObject { | ||||
| public: | ||||
|     explicit ServerSession(KernelCore& kernel); | ||||
|     ~ServerSession() override; | ||||
|  | ||||
|     std::string GetTypeName() const override { | ||||
|         return "ServerSession"; | ||||
|     } | ||||
| @@ -59,7 +62,7 @@ public: | ||||
|         return parent.get(); | ||||
|     } | ||||
|  | ||||
|     using SessionPair = std::pair<SharedPtr<ServerSession>, SharedPtr<ClientSession>>; | ||||
|     using SessionPair = std::pair<std::shared_ptr<ServerSession>, std::shared_ptr<ClientSession>>; | ||||
|  | ||||
|     /** | ||||
|      * Creates a pair of ServerSession and an associated ClientSession. | ||||
| @@ -69,7 +72,7 @@ public: | ||||
|      * @return The created session tuple | ||||
|      */ | ||||
|     static SessionPair CreateSessionPair(KernelCore& kernel, const std::string& name = "Unknown", | ||||
|                                          SharedPtr<ClientPort> client_port = nullptr); | ||||
|                                          std::shared_ptr<ClientPort> client_port = nullptr); | ||||
|  | ||||
|     /** | ||||
|      * Sets the HLE handler for the session. This handler will be called to service IPC requests | ||||
| @@ -85,7 +88,7 @@ public: | ||||
|      * @param thread Thread that initiated the request. | ||||
|      * @returns ResultCode from the operation. | ||||
|      */ | ||||
|     ResultCode HandleSyncRequest(SharedPtr<Thread> thread); | ||||
|     ResultCode HandleSyncRequest(std::shared_ptr<Thread> thread); | ||||
|  | ||||
|     bool ShouldWait(const Thread* thread) const override; | ||||
|  | ||||
| @@ -118,9 +121,6 @@ public: | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     explicit ServerSession(KernelCore& kernel); | ||||
|     ~ServerSession() override; | ||||
|  | ||||
|     /** | ||||
|      * Creates a server session. The server session can have an optional HLE handler, | ||||
|      * which will be invoked to handle the IPC requests that this session receives. | ||||
| @@ -128,8 +128,8 @@ private: | ||||
|      * @param name Optional name of the server session. | ||||
|      * @return The created server session | ||||
|      */ | ||||
|     static ResultVal<SharedPtr<ServerSession>> Create(KernelCore& kernel, | ||||
|                                                       std::string name = "Unknown"); | ||||
|     static ResultVal<std::shared_ptr<ServerSession>> Create(KernelCore& kernel, | ||||
|                                                             std::string name = "Unknown"); | ||||
|  | ||||
|     /// Handles a SyncRequest to a domain, forwarding the request to the proper object or closing an | ||||
|     /// object handle. | ||||
| @@ -147,12 +147,12 @@ private: | ||||
|     /// List of threads that are pending a response after a sync request. This list is processed in | ||||
|     /// a LIFO manner, thus, the last request will be dispatched first. | ||||
|     /// TODO(Subv): Verify if this is indeed processed in LIFO using a hardware test. | ||||
|     std::vector<SharedPtr<Thread>> pending_requesting_threads; | ||||
|     std::vector<std::shared_ptr<Thread>> pending_requesting_threads; | ||||
|  | ||||
|     /// Thread whose request is currently being handled. A request is considered "handled" when a | ||||
|     /// response is sent via svcReplyAndReceive. | ||||
|     /// TODO(Subv): Find a better name for this. | ||||
|     SharedPtr<Thread> currently_handling; | ||||
|     std::shared_ptr<Thread> currently_handling; | ||||
|  | ||||
|     /// When set to True, converts the session to a domain at the end of the command | ||||
|     bool convert_to_domain{}; | ||||
|   | ||||
| @@ -20,8 +20,8 @@ class ServerSession; | ||||
|  */ | ||||
| class Session final { | ||||
| public: | ||||
|     ClientSession* client = nullptr; ///< The client endpoint of the session. | ||||
|     ServerSession* server = nullptr; ///< The server endpoint of the session. | ||||
|     SharedPtr<ClientPort> port;      ///< The port that this session is associated with (optional). | ||||
|     ClientSession* client = nullptr;  ///< The client endpoint of the session. | ||||
|     ServerSession* server = nullptr;  ///< The server endpoint of the session. | ||||
|     std::shared_ptr<ClientPort> port; ///< The port that this session is associated with (optional). | ||||
| }; | ||||
| } // namespace Kernel | ||||
|   | ||||
| @@ -15,11 +15,12 @@ namespace Kernel { | ||||
| SharedMemory::SharedMemory(KernelCore& kernel) : Object{kernel} {} | ||||
| SharedMemory::~SharedMemory() = default; | ||||
|  | ||||
| SharedPtr<SharedMemory> SharedMemory::Create(KernelCore& kernel, Process* owner_process, u64 size, | ||||
|                                              MemoryPermission permissions, | ||||
|                                              MemoryPermission other_permissions, VAddr address, | ||||
|                                              MemoryRegion region, std::string name) { | ||||
|     SharedPtr<SharedMemory> shared_memory(new SharedMemory(kernel)); | ||||
| std::shared_ptr<SharedMemory> SharedMemory::Create(KernelCore& kernel, Process* owner_process, | ||||
|                                                    u64 size, MemoryPermission permissions, | ||||
|                                                    MemoryPermission other_permissions, | ||||
|                                                    VAddr address, MemoryRegion region, | ||||
|                                                    std::string name) { | ||||
|     std::shared_ptr<SharedMemory> shared_memory = std::make_shared<SharedMemory>(kernel); | ||||
|  | ||||
|     shared_memory->owner_process = owner_process; | ||||
|     shared_memory->name = std::move(name); | ||||
| @@ -58,10 +59,10 @@ SharedPtr<SharedMemory> SharedMemory::Create(KernelCore& kernel, Process* owner_ | ||||
|     return shared_memory; | ||||
| } | ||||
|  | ||||
| SharedPtr<SharedMemory> SharedMemory::CreateForApplet( | ||||
| std::shared_ptr<SharedMemory> SharedMemory::CreateForApplet( | ||||
|     KernelCore& kernel, std::shared_ptr<Kernel::PhysicalMemory> heap_block, std::size_t offset, | ||||
|     u64 size, MemoryPermission permissions, MemoryPermission other_permissions, std::string name) { | ||||
|     SharedPtr<SharedMemory> shared_memory(new SharedMemory(kernel)); | ||||
|     std::shared_ptr<SharedMemory> shared_memory = std::make_shared<SharedMemory>(kernel); | ||||
|  | ||||
|     shared_memory->owner_process = nullptr; | ||||
|     shared_memory->name = std::move(name); | ||||
|   | ||||
| @@ -33,6 +33,9 @@ enum class MemoryPermission : u32 { | ||||
|  | ||||
| class SharedMemory final : public Object { | ||||
| public: | ||||
|     explicit SharedMemory(KernelCore& kernel); | ||||
|     ~SharedMemory() override; | ||||
|  | ||||
|     /** | ||||
|      * Creates a shared memory object. | ||||
|      * @param kernel The kernel instance to create a shared memory instance under. | ||||
| @@ -46,11 +49,12 @@ public: | ||||
|      * linear heap. | ||||
|      * @param name Optional object name, used for debugging purposes. | ||||
|      */ | ||||
|     static SharedPtr<SharedMemory> Create(KernelCore& kernel, Process* owner_process, u64 size, | ||||
|                                           MemoryPermission permissions, | ||||
|                                           MemoryPermission other_permissions, VAddr address = 0, | ||||
|                                           MemoryRegion region = MemoryRegion::BASE, | ||||
|                                           std::string name = "Unknown"); | ||||
|     static std::shared_ptr<SharedMemory> Create(KernelCore& kernel, Process* owner_process, | ||||
|                                                 u64 size, MemoryPermission permissions, | ||||
|                                                 MemoryPermission other_permissions, | ||||
|                                                 VAddr address = 0, | ||||
|                                                 MemoryRegion region = MemoryRegion::BASE, | ||||
|                                                 std::string name = "Unknown"); | ||||
|  | ||||
|     /** | ||||
|      * Creates a shared memory object from a block of memory managed by an HLE applet. | ||||
| @@ -63,7 +67,7 @@ public: | ||||
|      * block. | ||||
|      * @param name Optional object name, used for debugging purposes. | ||||
|      */ | ||||
|     static SharedPtr<SharedMemory> CreateForApplet( | ||||
|     static std::shared_ptr<SharedMemory> CreateForApplet( | ||||
|         KernelCore& kernel, std::shared_ptr<Kernel::PhysicalMemory> heap_block, std::size_t offset, | ||||
|         u64 size, MemoryPermission permissions, MemoryPermission other_permissions, | ||||
|         std::string name = "Unknown Applet"); | ||||
| @@ -130,9 +134,6 @@ public: | ||||
|     const u8* GetPointer(std::size_t offset = 0) const; | ||||
|  | ||||
| private: | ||||
|     explicit SharedMemory(KernelCore& kernel); | ||||
|     ~SharedMemory() override; | ||||
|  | ||||
|     /// Backing memory for this shared memory block. | ||||
|     std::shared_ptr<PhysicalMemory> backing_block; | ||||
|     /// Offset into the backing block for this shared memory. | ||||
|   | ||||
| @@ -359,7 +359,7 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle, | ||||
|  | ||||
|     auto client_port = it->second; | ||||
|  | ||||
|     SharedPtr<ClientSession> client_session; | ||||
|     std::shared_ptr<ClientSession> client_session; | ||||
|     CASCADE_RESULT(client_session, client_port->Connect()); | ||||
|  | ||||
|     // Return the client session | ||||
| @@ -371,7 +371,7 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle, | ||||
| /// Makes a blocking IPC call to an OS service. | ||||
| static ResultCode SendSyncRequest(Core::System& system, Handle handle) { | ||||
|     const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | ||||
|     SharedPtr<ClientSession> session = handle_table.Get<ClientSession>(handle); | ||||
|     std::shared_ptr<ClientSession> session = handle_table.Get<ClientSession>(handle); | ||||
|     if (!session) { | ||||
|         LOG_ERROR(Kernel_SVC, "called with invalid handle=0x{:08X}", handle); | ||||
|         return ERR_INVALID_HANDLE; | ||||
| @@ -391,7 +391,7 @@ static ResultCode GetThreadId(Core::System& system, u64* thread_id, Handle threa | ||||
|     LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle); | ||||
|  | ||||
|     const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | ||||
|     const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); | ||||
|     const std::shared_ptr<Thread> thread = handle_table.Get<Thread>(thread_handle); | ||||
|     if (!thread) { | ||||
|         LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", thread_handle); | ||||
|         return ERR_INVALID_HANDLE; | ||||
| @@ -406,13 +406,13 @@ static ResultCode GetProcessId(Core::System& system, u64* process_id, Handle han | ||||
|     LOG_DEBUG(Kernel_SVC, "called handle=0x{:08X}", handle); | ||||
|  | ||||
|     const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | ||||
|     const SharedPtr<Process> process = handle_table.Get<Process>(handle); | ||||
|     const std::shared_ptr<Process> process = handle_table.Get<Process>(handle); | ||||
|     if (process) { | ||||
|         *process_id = process->GetProcessID(); | ||||
|         return RESULT_SUCCESS; | ||||
|     } | ||||
|  | ||||
|     const SharedPtr<Thread> thread = handle_table.Get<Thread>(handle); | ||||
|     const std::shared_ptr<Thread> thread = handle_table.Get<Thread>(handle); | ||||
|     if (thread) { | ||||
|         const Process* const owner_process = thread->GetOwnerProcess(); | ||||
|         if (!owner_process) { | ||||
| @@ -431,8 +431,8 @@ static ResultCode GetProcessId(Core::System& system, u64* process_id, Handle han | ||||
| } | ||||
|  | ||||
| /// Default thread wakeup callback for WaitSynchronization | ||||
| static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thread> thread, | ||||
|                                         SharedPtr<WaitObject> object, std::size_t index) { | ||||
| static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, | ||||
|                                         std::shared_ptr<WaitObject> object, std::size_t index) { | ||||
|     ASSERT(thread->GetStatus() == ThreadStatus::WaitSynch); | ||||
|  | ||||
|     if (reason == ThreadWakeupReason::Timeout) { | ||||
| @@ -512,7 +512,7 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr | ||||
|     } | ||||
|  | ||||
|     for (auto& object : objects) { | ||||
|         object->AddWaitingThread(thread); | ||||
|         object->AddWaitingThread(SharedFrom(thread)); | ||||
|     } | ||||
|  | ||||
|     thread->SetWaitObjects(std::move(objects)); | ||||
| @@ -532,7 +532,7 @@ static ResultCode CancelSynchronization(Core::System& system, Handle thread_hand | ||||
|     LOG_TRACE(Kernel_SVC, "called thread=0x{:X}", thread_handle); | ||||
|  | ||||
|     const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | ||||
|     SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); | ||||
|     std::shared_ptr<Thread> thread = handle_table.Get<Thread>(thread_handle); | ||||
|     if (!thread) { | ||||
|         LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}", | ||||
|                   thread_handle); | ||||
| @@ -941,7 +941,7 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha | ||||
|         const auto& core_timing = system.CoreTiming(); | ||||
|         const auto& scheduler = system.CurrentScheduler(); | ||||
|         const auto* const current_thread = scheduler.GetCurrentThread(); | ||||
|         const bool same_thread = current_thread == thread; | ||||
|         const bool same_thread = current_thread == thread.get(); | ||||
|  | ||||
|         const u64 prev_ctx_ticks = scheduler.GetLastContextSwitchTicks(); | ||||
|         u64 out_ticks = 0; | ||||
| @@ -1051,7 +1051,7 @@ static ResultCode SetThreadActivity(Core::System& system, Handle handle, u32 act | ||||
|     } | ||||
|  | ||||
|     const auto* current_process = system.Kernel().CurrentProcess(); | ||||
|     const SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle); | ||||
|     const std::shared_ptr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle); | ||||
|     if (!thread) { | ||||
|         LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle); | ||||
|         return ERR_INVALID_HANDLE; | ||||
| @@ -1067,7 +1067,7 @@ static ResultCode SetThreadActivity(Core::System& system, Handle handle, u32 act | ||||
|         return ERR_INVALID_HANDLE; | ||||
|     } | ||||
|  | ||||
|     if (thread == system.CurrentScheduler().GetCurrentThread()) { | ||||
|     if (thread.get() == system.CurrentScheduler().GetCurrentThread()) { | ||||
|         LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread"); | ||||
|         return ERR_BUSY; | ||||
|     } | ||||
| @@ -1083,7 +1083,7 @@ static ResultCode GetThreadContext(Core::System& system, VAddr thread_context, H | ||||
|     LOG_DEBUG(Kernel_SVC, "called, context=0x{:08X}, thread=0x{:X}", thread_context, handle); | ||||
|  | ||||
|     const auto* current_process = system.Kernel().CurrentProcess(); | ||||
|     const SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle); | ||||
|     const std::shared_ptr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle); | ||||
|     if (!thread) { | ||||
|         LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle); | ||||
|         return ERR_INVALID_HANDLE; | ||||
| @@ -1099,7 +1099,7 @@ static ResultCode GetThreadContext(Core::System& system, VAddr thread_context, H | ||||
|         return ERR_INVALID_HANDLE; | ||||
|     } | ||||
|  | ||||
|     if (thread == system.CurrentScheduler().GetCurrentThread()) { | ||||
|     if (thread.get() == system.CurrentScheduler().GetCurrentThread()) { | ||||
|         LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread"); | ||||
|         return ERR_BUSY; | ||||
|     } | ||||
| @@ -1124,7 +1124,7 @@ static ResultCode GetThreadPriority(Core::System& system, u32* priority, Handle | ||||
|     LOG_TRACE(Kernel_SVC, "called"); | ||||
|  | ||||
|     const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | ||||
|     const SharedPtr<Thread> thread = handle_table.Get<Thread>(handle); | ||||
|     const std::shared_ptr<Thread> thread = handle_table.Get<Thread>(handle); | ||||
|     if (!thread) { | ||||
|         LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle); | ||||
|         return ERR_INVALID_HANDLE; | ||||
| @@ -1148,7 +1148,7 @@ static ResultCode SetThreadPriority(Core::System& system, Handle handle, u32 pri | ||||
|  | ||||
|     const auto* const current_process = system.Kernel().CurrentProcess(); | ||||
|  | ||||
|     SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle); | ||||
|     std::shared_ptr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle); | ||||
|     if (!thread) { | ||||
|         LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle); | ||||
|         return ERR_INVALID_HANDLE; | ||||
| @@ -1268,7 +1268,7 @@ static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_add | ||||
|                                      VAddr address) { | ||||
|     LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address); | ||||
|     const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | ||||
|     SharedPtr<Process> process = handle_table.Get<Process>(process_handle); | ||||
|     std::shared_ptr<Process> process = handle_table.Get<Process>(process_handle); | ||||
|     if (!process) { | ||||
|         LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}", | ||||
|                   process_handle); | ||||
| @@ -1496,7 +1496,7 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e | ||||
|     } | ||||
|  | ||||
|     auto& kernel = system.Kernel(); | ||||
|     CASCADE_RESULT(SharedPtr<Thread> thread, | ||||
|     CASCADE_RESULT(std::shared_ptr<Thread> thread, | ||||
|                    Thread::Create(kernel, "", entry_point, priority, arg, processor_id, stack_top, | ||||
|                                   *current_process)); | ||||
|  | ||||
| @@ -1522,7 +1522,7 @@ static ResultCode StartThread(Core::System& system, Handle thread_handle) { | ||||
|     LOG_DEBUG(Kernel_SVC, "called thread=0x{:08X}", thread_handle); | ||||
|  | ||||
|     const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | ||||
|     const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); | ||||
|     const std::shared_ptr<Thread> thread = handle_table.Get<Thread>(thread_handle); | ||||
|     if (!thread) { | ||||
|         LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}", | ||||
|                   thread_handle); | ||||
| @@ -1546,7 +1546,7 @@ static void ExitThread(Core::System& system) { | ||||
|  | ||||
|     auto* const current_thread = system.CurrentScheduler().GetCurrentThread(); | ||||
|     current_thread->Stop(); | ||||
|     system.GlobalScheduler().RemoveThread(current_thread); | ||||
|     system.GlobalScheduler().RemoveThread(SharedFrom(current_thread)); | ||||
|     system.PrepareReschedule(); | ||||
| } | ||||
|  | ||||
| @@ -1618,7 +1618,7 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_add | ||||
|  | ||||
|     auto* const current_process = system.Kernel().CurrentProcess(); | ||||
|     const auto& handle_table = current_process->GetHandleTable(); | ||||
|     SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); | ||||
|     std::shared_ptr<Thread> thread = handle_table.Get<Thread>(thread_handle); | ||||
|     ASSERT(thread); | ||||
|  | ||||
|     const auto release_result = current_process->GetMutex().Release(mutex_addr); | ||||
| @@ -1626,13 +1626,13 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_add | ||||
|         return release_result; | ||||
|     } | ||||
|  | ||||
|     SharedPtr<Thread> current_thread = system.CurrentScheduler().GetCurrentThread(); | ||||
|     Thread* current_thread = system.CurrentScheduler().GetCurrentThread(); | ||||
|     current_thread->SetCondVarWaitAddress(condition_variable_addr); | ||||
|     current_thread->SetMutexWaitAddress(mutex_addr); | ||||
|     current_thread->SetWaitHandle(thread_handle); | ||||
|     current_thread->SetStatus(ThreadStatus::WaitCondVar); | ||||
|     current_thread->InvalidateWakeupCallback(); | ||||
|     current_process->InsertConditionVariableThread(current_thread); | ||||
|     current_process->InsertConditionVariableThread(SharedFrom(current_thread)); | ||||
|  | ||||
|     current_thread->WakeAfterDelay(nano_seconds); | ||||
|  | ||||
| @@ -1652,7 +1652,7 @@ static ResultCode SignalProcessWideKey(Core::System& system, VAddr condition_var | ||||
|  | ||||
|     // Retrieve a list of all threads that are waiting for this condition variable. | ||||
|     auto* const current_process = system.Kernel().CurrentProcess(); | ||||
|     std::vector<SharedPtr<Thread>> waiting_threads = | ||||
|     std::vector<std::shared_ptr<Thread>> waiting_threads = | ||||
|         current_process->GetConditionVariableThreads(condition_variable_addr); | ||||
|  | ||||
|     // Only process up to 'target' threads, unless 'target' is less equal 0, in which case process | ||||
| @@ -1969,7 +1969,7 @@ static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle, | ||||
|     LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle); | ||||
|  | ||||
|     const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | ||||
|     const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); | ||||
|     const std::shared_ptr<Thread> thread = handle_table.Get<Thread>(thread_handle); | ||||
|     if (!thread) { | ||||
|         LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}", | ||||
|                   thread_handle); | ||||
| @@ -2028,7 +2028,7 @@ static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle, | ||||
|     } | ||||
|  | ||||
|     const auto& handle_table = current_process->GetHandleTable(); | ||||
|     const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); | ||||
|     const std::shared_ptr<Thread> thread = handle_table.Get<Thread>(thread_handle); | ||||
|     if (!thread) { | ||||
|         LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}", | ||||
|                   thread_handle); | ||||
|   | ||||
| @@ -50,7 +50,7 @@ void Thread::Stop() { | ||||
|  | ||||
|     // Clean up any dangling references in objects that this thread was waiting for | ||||
|     for (auto& wait_object : wait_objects) { | ||||
|         wait_object->RemoveWaitingThread(this); | ||||
|         wait_object->RemoveWaitingThread(SharedFrom(this)); | ||||
|     } | ||||
|     wait_objects.clear(); | ||||
|  | ||||
| @@ -147,9 +147,10 @@ static void ResetThreadContext(Core::ARM_Interface::ThreadContext& context, VAdd | ||||
|     context.fpcr = 0x03C00000; | ||||
| } | ||||
|  | ||||
| ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name, VAddr entry_point, | ||||
|                                             u32 priority, u64 arg, s32 processor_id, | ||||
|                                             VAddr stack_top, Process& owner_process) { | ||||
| ResultVal<std::shared_ptr<Thread>> Thread::Create(KernelCore& kernel, std::string name, | ||||
|                                                   VAddr entry_point, u32 priority, u64 arg, | ||||
|                                                   s32 processor_id, VAddr stack_top, | ||||
|                                                   Process& owner_process) { | ||||
|     // Check if priority is in ranged. Lowest priority -> highest priority id. | ||||
|     if (priority > THREADPRIO_LOWEST) { | ||||
|         LOG_ERROR(Kernel_SVC, "Invalid thread priority: {}", priority); | ||||
| @@ -168,7 +169,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name | ||||
|     } | ||||
|  | ||||
|     auto& system = Core::System::GetInstance(); | ||||
|     SharedPtr<Thread> thread(new Thread(kernel)); | ||||
|     std::shared_ptr<Thread> thread = std::make_shared<Thread>(kernel); | ||||
|  | ||||
|     thread->thread_id = kernel.CreateNewThreadID(); | ||||
|     thread->status = ThreadStatus::Dormant; | ||||
| @@ -197,7 +198,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name | ||||
|     // to initialize the context | ||||
|     ResetThreadContext(thread->context, stack_top, entry_point, arg); | ||||
|  | ||||
|     return MakeResult<SharedPtr<Thread>>(std::move(thread)); | ||||
|     return MakeResult<std::shared_ptr<Thread>>(std::move(thread)); | ||||
| } | ||||
|  | ||||
| void Thread::SetPriority(u32 priority) { | ||||
| @@ -215,7 +216,7 @@ void Thread::SetWaitSynchronizationOutput(s32 output) { | ||||
|     context.cpu_registers[1] = output; | ||||
| } | ||||
|  | ||||
| s32 Thread::GetWaitObjectIndex(const WaitObject* object) const { | ||||
| s32 Thread::GetWaitObjectIndex(std::shared_ptr<WaitObject> object) const { | ||||
|     ASSERT_MSG(!wait_objects.empty(), "Thread is not waiting for anything"); | ||||
|     const auto match = std::find(wait_objects.rbegin(), wait_objects.rend(), object); | ||||
|     return static_cast<s32>(std::distance(match, wait_objects.rend()) - 1); | ||||
| @@ -255,8 +256,8 @@ void Thread::SetStatus(ThreadStatus new_status) { | ||||
|     status = new_status; | ||||
| } | ||||
|  | ||||
| void Thread::AddMutexWaiter(SharedPtr<Thread> thread) { | ||||
|     if (thread->lock_owner == this) { | ||||
| void Thread::AddMutexWaiter(std::shared_ptr<Thread> thread) { | ||||
|     if (thread->lock_owner.get() == this) { | ||||
|         // If the thread is already waiting for this thread to release the mutex, ensure that the | ||||
|         // waiters list is consistent and return without doing anything. | ||||
|         const auto iter = std::find(wait_mutex_threads.begin(), wait_mutex_threads.end(), thread); | ||||
| @@ -276,13 +277,13 @@ void Thread::AddMutexWaiter(SharedPtr<Thread> thread) { | ||||
|         wait_mutex_threads.begin(), wait_mutex_threads.end(), | ||||
|         [&thread](const auto& entry) { return entry->GetPriority() > thread->GetPriority(); }); | ||||
|     wait_mutex_threads.insert(insertion_point, thread); | ||||
|     thread->lock_owner = this; | ||||
|     thread->lock_owner = SharedFrom(this); | ||||
|  | ||||
|     UpdatePriority(); | ||||
| } | ||||
|  | ||||
| void Thread::RemoveMutexWaiter(SharedPtr<Thread> thread) { | ||||
|     ASSERT(thread->lock_owner == this); | ||||
| void Thread::RemoveMutexWaiter(std::shared_ptr<Thread> thread) { | ||||
|     ASSERT(thread->lock_owner.get() == this); | ||||
|  | ||||
|     // Ensure that the thread is in the list of mutex waiters | ||||
|     const auto iter = std::find(wait_mutex_threads.begin(), wait_mutex_threads.end(), thread); | ||||
| @@ -310,13 +311,13 @@ void Thread::UpdatePriority() { | ||||
|     } | ||||
|  | ||||
|     if (GetStatus() == ThreadStatus::WaitCondVar) { | ||||
|         owner_process->RemoveConditionVariableThread(this); | ||||
|         owner_process->RemoveConditionVariableThread(SharedFrom(this)); | ||||
|     } | ||||
|  | ||||
|     SetCurrentPriority(new_priority); | ||||
|  | ||||
|     if (GetStatus() == ThreadStatus::WaitCondVar) { | ||||
|         owner_process->InsertConditionVariableThread(this); | ||||
|         owner_process->InsertConditionVariableThread(SharedFrom(this)); | ||||
|     } | ||||
|  | ||||
|     if (!lock_owner) { | ||||
| @@ -325,8 +326,8 @@ void Thread::UpdatePriority() { | ||||
|  | ||||
|     // Ensure that the thread is within the correct location in the waiting list. | ||||
|     auto old_owner = lock_owner; | ||||
|     lock_owner->RemoveMutexWaiter(this); | ||||
|     old_owner->AddMutexWaiter(this); | ||||
|     lock_owner->RemoveMutexWaiter(SharedFrom(this)); | ||||
|     old_owner->AddMutexWaiter(SharedFrom(this)); | ||||
|  | ||||
|     // Recursively update the priority of the thread that depends on the priority of this one. | ||||
|     lock_owner->UpdatePriority(); | ||||
| @@ -339,11 +340,11 @@ void Thread::ChangeCore(u32 core, u64 mask) { | ||||
| bool Thread::AllWaitObjectsReady() const { | ||||
|     return std::none_of( | ||||
|         wait_objects.begin(), wait_objects.end(), | ||||
|         [this](const SharedPtr<WaitObject>& object) { return object->ShouldWait(this); }); | ||||
|         [this](const std::shared_ptr<WaitObject>& object) { return object->ShouldWait(this); }); | ||||
| } | ||||
|  | ||||
| bool Thread::InvokeWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thread> thread, | ||||
|                                   SharedPtr<WaitObject> object, std::size_t index) { | ||||
| bool Thread::InvokeWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, | ||||
|                                   std::shared_ptr<WaitObject> object, std::size_t index) { | ||||
|     ASSERT(wakeup_callback); | ||||
|     return wakeup_callback(reason, std::move(thread), std::move(object), index); | ||||
| } | ||||
|   | ||||
| @@ -97,14 +97,18 @@ enum class ThreadSchedMasks : u32 { | ||||
|  | ||||
| class Thread final : public WaitObject { | ||||
| public: | ||||
|     using MutexWaitingThreads = std::vector<SharedPtr<Thread>>; | ||||
|     explicit Thread(KernelCore& kernel); | ||||
|     ~Thread() override; | ||||
|  | ||||
|     using MutexWaitingThreads = std::vector<std::shared_ptr<Thread>>; | ||||
|  | ||||
|     using ThreadContext = Core::ARM_Interface::ThreadContext; | ||||
|  | ||||
|     using ThreadWaitObjects = std::vector<SharedPtr<WaitObject>>; | ||||
|     using ThreadWaitObjects = std::vector<std::shared_ptr<WaitObject>>; | ||||
|  | ||||
|     using WakeupCallback = std::function<bool(ThreadWakeupReason reason, SharedPtr<Thread> thread, | ||||
|                                               SharedPtr<WaitObject> object, std::size_t index)>; | ||||
|     using WakeupCallback = | ||||
|         std::function<bool(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, | ||||
|                            std::shared_ptr<WaitObject> object, std::size_t index)>; | ||||
|  | ||||
|     /** | ||||
|      * Creates and returns a new thread. The new thread is immediately scheduled | ||||
| @@ -118,10 +122,10 @@ public: | ||||
|      * @param owner_process The parent process for the thread | ||||
|      * @return A shared pointer to the newly created thread | ||||
|      */ | ||||
|     static ResultVal<SharedPtr<Thread>> Create(KernelCore& kernel, std::string name, | ||||
|                                                VAddr entry_point, u32 priority, u64 arg, | ||||
|                                                s32 processor_id, VAddr stack_top, | ||||
|                                                Process& owner_process); | ||||
|     static ResultVal<std::shared_ptr<Thread>> Create(KernelCore& kernel, std::string name, | ||||
|                                                      VAddr entry_point, u32 priority, u64 arg, | ||||
|                                                      s32 processor_id, VAddr stack_top, | ||||
|                                                      Process& owner_process); | ||||
|  | ||||
|     std::string GetName() const override { | ||||
|         return name; | ||||
| @@ -166,10 +170,10 @@ public: | ||||
|     void SetPriority(u32 priority); | ||||
|  | ||||
|     /// Adds a thread to the list of threads that are waiting for a lock held by this thread. | ||||
|     void AddMutexWaiter(SharedPtr<Thread> thread); | ||||
|     void AddMutexWaiter(std::shared_ptr<Thread> thread); | ||||
|  | ||||
|     /// Removes a thread from the list of threads that are waiting for a lock held by this thread. | ||||
|     void RemoveMutexWaiter(SharedPtr<Thread> thread); | ||||
|     void RemoveMutexWaiter(std::shared_ptr<Thread> thread); | ||||
|  | ||||
|     /// Recalculates the current priority taking into account priority inheritance. | ||||
|     void UpdatePriority(); | ||||
| @@ -229,7 +233,7 @@ public: | ||||
|      * | ||||
|      * @param object Object to query the index of. | ||||
|      */ | ||||
|     s32 GetWaitObjectIndex(const WaitObject* object) const; | ||||
|     s32 GetWaitObjectIndex(std::shared_ptr<WaitObject> object) const; | ||||
|  | ||||
|     /** | ||||
|      * Stops a thread, invalidating it from further use | ||||
| @@ -320,7 +324,7 @@ public: | ||||
|  | ||||
|     void ClearWaitObjects() { | ||||
|         for (const auto& waiting_object : wait_objects) { | ||||
|             waiting_object->RemoveWaitingThread(this); | ||||
|             waiting_object->RemoveWaitingThread(SharedFrom(this)); | ||||
|         } | ||||
|         wait_objects.clear(); | ||||
|     } | ||||
| @@ -336,7 +340,7 @@ public: | ||||
|         return lock_owner.get(); | ||||
|     } | ||||
|  | ||||
|     void SetLockOwner(SharedPtr<Thread> owner) { | ||||
|     void SetLockOwner(std::shared_ptr<Thread> owner) { | ||||
|         lock_owner = std::move(owner); | ||||
|     } | ||||
|  | ||||
| @@ -390,8 +394,8 @@ public: | ||||
|      * @pre A valid wakeup callback has been set. Violating this precondition | ||||
|      *      will cause an assertion to trigger. | ||||
|      */ | ||||
|     bool InvokeWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thread> thread, | ||||
|                               SharedPtr<WaitObject> object, std::size_t index); | ||||
|     bool InvokeWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, | ||||
|                               std::shared_ptr<WaitObject> object, std::size_t index); | ||||
|  | ||||
|     u32 GetIdealCore() const { | ||||
|         return ideal_core; | ||||
| @@ -449,9 +453,6 @@ public: | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     explicit Thread(KernelCore& kernel); | ||||
|     ~Thread() override; | ||||
|  | ||||
|     void SetSchedulingStatus(ThreadSchedStatus new_status); | ||||
|     void SetCurrentPriority(u32 new_priority); | ||||
|     ResultCode SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask); | ||||
| @@ -499,7 +500,7 @@ private: | ||||
|     MutexWaitingThreads wait_mutex_threads; | ||||
|  | ||||
|     /// Thread that owns the lock that this thread is waiting for. | ||||
|     SharedPtr<Thread> lock_owner; | ||||
|     std::shared_ptr<Thread> lock_owner; | ||||
|  | ||||
|     /// If waiting on a ConditionVariable, this is the ConditionVariable address | ||||
|     VAddr condvar_wait_address = 0; | ||||
|   | ||||
| @@ -14,9 +14,9 @@ namespace Kernel { | ||||
| TransferMemory::TransferMemory(KernelCore& kernel) : Object{kernel} {} | ||||
| TransferMemory::~TransferMemory() = default; | ||||
|  | ||||
| SharedPtr<TransferMemory> TransferMemory::Create(KernelCore& kernel, VAddr base_address, u64 size, | ||||
|                                                  MemoryPermission permissions) { | ||||
|     SharedPtr<TransferMemory> transfer_memory{new TransferMemory(kernel)}; | ||||
| std::shared_ptr<TransferMemory> TransferMemory::Create(KernelCore& kernel, VAddr base_address, | ||||
|                                                        u64 size, MemoryPermission permissions) { | ||||
|     std::shared_ptr<TransferMemory> transfer_memory{std::make_shared<TransferMemory>(kernel)}; | ||||
|  | ||||
|     transfer_memory->base_address = base_address; | ||||
|     transfer_memory->memory_size = size; | ||||
|   | ||||
| @@ -27,10 +27,13 @@ enum class MemoryPermission : u32; | ||||
| /// | ||||
| class TransferMemory final : public Object { | ||||
| public: | ||||
|     explicit TransferMemory(KernelCore& kernel); | ||||
|     ~TransferMemory() override; | ||||
|  | ||||
|     static constexpr HandleType HANDLE_TYPE = HandleType::TransferMemory; | ||||
|  | ||||
|     static SharedPtr<TransferMemory> Create(KernelCore& kernel, VAddr base_address, u64 size, | ||||
|                                             MemoryPermission permissions); | ||||
|     static std::shared_ptr<TransferMemory> Create(KernelCore& kernel, VAddr base_address, u64 size, | ||||
|                                                   MemoryPermission permissions); | ||||
|  | ||||
|     TransferMemory(const TransferMemory&) = delete; | ||||
|     TransferMemory& operator=(const TransferMemory&) = delete; | ||||
| @@ -79,9 +82,6 @@ public: | ||||
|     ResultCode UnmapMemory(VAddr address, u64 size); | ||||
|  | ||||
| private: | ||||
|     explicit TransferMemory(KernelCore& kernel); | ||||
|     ~TransferMemory() override; | ||||
|  | ||||
|     /// Memory block backing this instance. | ||||
|     std::shared_ptr<PhysicalMemory> backing_block; | ||||
|  | ||||
|   | ||||
| @@ -18,13 +18,13 @@ namespace Kernel { | ||||
| WaitObject::WaitObject(KernelCore& kernel) : Object{kernel} {} | ||||
| WaitObject::~WaitObject() = default; | ||||
|  | ||||
| void WaitObject::AddWaitingThread(SharedPtr<Thread> thread) { | ||||
| void WaitObject::AddWaitingThread(std::shared_ptr<Thread> thread) { | ||||
|     auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread); | ||||
|     if (itr == waiting_threads.end()) | ||||
|         waiting_threads.push_back(std::move(thread)); | ||||
| } | ||||
|  | ||||
| void WaitObject::RemoveWaitingThread(Thread* thread) { | ||||
| void WaitObject::RemoveWaitingThread(std::shared_ptr<Thread> thread) { | ||||
|     auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread); | ||||
|     // If a thread passed multiple handles to the same object, | ||||
|     // the kernel might attempt to remove the thread from the object's | ||||
| @@ -33,7 +33,7 @@ void WaitObject::RemoveWaitingThread(Thread* thread) { | ||||
|         waiting_threads.erase(itr); | ||||
| } | ||||
|  | ||||
| SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() const { | ||||
| std::shared_ptr<Thread> WaitObject::GetHighestPriorityReadyThread() const { | ||||
|     Thread* candidate = nullptr; | ||||
|     u32 candidate_priority = THREADPRIO_LOWEST + 1; | ||||
|  | ||||
| @@ -64,10 +64,10 @@ SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() const { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return candidate; | ||||
|     return SharedFrom(candidate); | ||||
| } | ||||
|  | ||||
| void WaitObject::WakeupWaitingThread(SharedPtr<Thread> thread) { | ||||
| void WaitObject::WakeupWaitingThread(std::shared_ptr<Thread> thread) { | ||||
|     ASSERT(!ShouldWait(thread.get())); | ||||
|  | ||||
|     if (!thread) { | ||||
| @@ -83,7 +83,7 @@ void WaitObject::WakeupWaitingThread(SharedPtr<Thread> thread) { | ||||
|         Acquire(thread.get()); | ||||
|     } | ||||
|  | ||||
|     const std::size_t index = thread->GetWaitObjectIndex(this); | ||||
|     const std::size_t index = thread->GetWaitObjectIndex(SharedFrom(this)); | ||||
|  | ||||
|     thread->ClearWaitObjects(); | ||||
|  | ||||
| @@ -91,7 +91,8 @@ void WaitObject::WakeupWaitingThread(SharedPtr<Thread> thread) { | ||||
|  | ||||
|     bool resume = true; | ||||
|     if (thread->HasWakeupCallback()) { | ||||
|         resume = thread->InvokeWakeupCallback(ThreadWakeupReason::Signal, thread, this, index); | ||||
|         resume = thread->InvokeWakeupCallback(ThreadWakeupReason::Signal, thread, SharedFrom(this), | ||||
|                                               index); | ||||
|     } | ||||
|     if (resume) { | ||||
|         thread->ResumeFromWait(); | ||||
| @@ -105,7 +106,7 @@ void WaitObject::WakeupAllWaitingThreads() { | ||||
|     } | ||||
| } | ||||
|  | ||||
| const std::vector<SharedPtr<Thread>>& WaitObject::GetWaitingThreads() const { | ||||
| const std::vector<std::shared_ptr<Thread>>& WaitObject::GetWaitingThreads() const { | ||||
|     return waiting_threads; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -33,13 +33,13 @@ public: | ||||
|      * Add a thread to wait on this object | ||||
|      * @param thread Pointer to thread to add | ||||
|      */ | ||||
|     void AddWaitingThread(SharedPtr<Thread> thread); | ||||
|     void AddWaitingThread(std::shared_ptr<Thread> thread); | ||||
|  | ||||
|     /** | ||||
|      * Removes a thread from waiting on this object (e.g. if it was resumed already) | ||||
|      * @param thread Pointer to thread to remove | ||||
|      */ | ||||
|     void RemoveWaitingThread(Thread* thread); | ||||
|     void RemoveWaitingThread(std::shared_ptr<Thread> thread); | ||||
|  | ||||
|     /** | ||||
|      * Wake up all threads waiting on this object that can be awoken, in priority order, | ||||
| @@ -51,24 +51,24 @@ public: | ||||
|      * Wakes up a single thread waiting on this object. | ||||
|      * @param thread Thread that is waiting on this object to wakeup. | ||||
|      */ | ||||
|     void WakeupWaitingThread(SharedPtr<Thread> thread); | ||||
|     void WakeupWaitingThread(std::shared_ptr<Thread> thread); | ||||
|  | ||||
|     /// Obtains the highest priority thread that is ready to run from this object's waiting list. | ||||
|     SharedPtr<Thread> GetHighestPriorityReadyThread() const; | ||||
|     std::shared_ptr<Thread> GetHighestPriorityReadyThread() const; | ||||
|  | ||||
|     /// Get a const reference to the waiting threads list for debug use | ||||
|     const std::vector<SharedPtr<Thread>>& GetWaitingThreads() const; | ||||
|     const std::vector<std::shared_ptr<Thread>>& GetWaitingThreads() const; | ||||
|  | ||||
| private: | ||||
|     /// Threads waiting for this object to become available | ||||
|     std::vector<SharedPtr<Thread>> waiting_threads; | ||||
|     std::vector<std::shared_ptr<Thread>> waiting_threads; | ||||
| }; | ||||
|  | ||||
| // Specialization of DynamicObjectCast for WaitObjects | ||||
| template <> | ||||
| inline SharedPtr<WaitObject> DynamicObjectCast<WaitObject>(SharedPtr<Object> object) { | ||||
| inline std::shared_ptr<WaitObject> DynamicObjectCast<WaitObject>(std::shared_ptr<Object> object) { | ||||
|     if (object != nullptr && object->IsWaitable()) { | ||||
|         return boost::static_pointer_cast<WaitObject>(object); | ||||
|         return std::static_pointer_cast<WaitObject>(object); | ||||
|     } | ||||
|     return nullptr; | ||||
| } | ||||
|   | ||||
| @@ -16,8 +16,8 @@ WritableEvent::WritableEvent(KernelCore& kernel) : Object{kernel} {} | ||||
| WritableEvent::~WritableEvent() = default; | ||||
|  | ||||
| EventPair WritableEvent::CreateEventPair(KernelCore& kernel, std::string name) { | ||||
|     SharedPtr<WritableEvent> writable_event(new WritableEvent(kernel)); | ||||
|     SharedPtr<ReadableEvent> readable_event(new ReadableEvent(kernel)); | ||||
|     std::shared_ptr<WritableEvent> writable_event(new WritableEvent(kernel)); | ||||
|     std::shared_ptr<ReadableEvent> readable_event(new ReadableEvent(kernel)); | ||||
|  | ||||
|     writable_event->name = name + ":Writable"; | ||||
|     writable_event->readable = readable_event; | ||||
| @@ -27,7 +27,7 @@ EventPair WritableEvent::CreateEventPair(KernelCore& kernel, std::string name) { | ||||
|     return {std::move(readable_event), std::move(writable_event)}; | ||||
| } | ||||
|  | ||||
| SharedPtr<ReadableEvent> WritableEvent::GetReadableEvent() const { | ||||
| std::shared_ptr<ReadableEvent> WritableEvent::GetReadableEvent() const { | ||||
|     return readable; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -13,8 +13,8 @@ class ReadableEvent; | ||||
| class WritableEvent; | ||||
|  | ||||
| struct EventPair { | ||||
|     SharedPtr<ReadableEvent> readable; | ||||
|     SharedPtr<WritableEvent> writable; | ||||
|     std::shared_ptr<ReadableEvent> readable; | ||||
|     std::shared_ptr<WritableEvent> writable; | ||||
| }; | ||||
|  | ||||
| class WritableEvent final : public Object { | ||||
| @@ -40,7 +40,7 @@ public: | ||||
|         return HANDLE_TYPE; | ||||
|     } | ||||
|  | ||||
|     SharedPtr<ReadableEvent> GetReadableEvent() const; | ||||
|     std::shared_ptr<ReadableEvent> GetReadableEvent() const; | ||||
|  | ||||
|     void Signal(); | ||||
|     void Clear(); | ||||
| @@ -49,7 +49,7 @@ public: | ||||
| private: | ||||
|     explicit WritableEvent(KernelCore& kernel); | ||||
|  | ||||
|     SharedPtr<ReadableEvent> readable; | ||||
|     std::shared_ptr<ReadableEvent> readable; | ||||
|  | ||||
|     std::string name; ///< Name of event (optional) | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 bunnei
					bunnei