mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	Kernel: Refactor synchronization to better match RE
This commit is contained in:
		
							parent
							
								
									c5aefe42aa
								
							
						
					
					
						commit
						d23d504d77
					
				| @ -183,6 +183,8 @@ add_library(core STATIC | ||||
|     hle/kernel/svc_wrap.h | ||||
|     hle/kernel/synchronization_object.cpp | ||||
|     hle/kernel/synchronization_object.h | ||||
|     hle/kernel/synchronization.cpp | ||||
|     hle/kernel/synchronization.h | ||||
|     hle/kernel/thread.cpp | ||||
|     hle/kernel/thread.h | ||||
|     hle/kernel/transfer_memory.cpp | ||||
|  | ||||
| @ -31,6 +31,11 @@ void ClientSession::Acquire(Thread* thread) { | ||||
|     UNIMPLEMENTED(); | ||||
| } | ||||
| 
 | ||||
| bool ClientSession::IsSignaled() const { | ||||
|     UNIMPLEMENTED(); | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| ResultVal<std::shared_ptr<ClientSession>> ClientSession::Create(KernelCore& kernel, | ||||
|                                                                 std::shared_ptr<Session> parent, | ||||
|                                                                 std::string name) { | ||||
|  | ||||
| @ -48,6 +48,8 @@ public: | ||||
| 
 | ||||
|     void Acquire(Thread* thread) override; | ||||
| 
 | ||||
|     bool IsSignaled() const override; | ||||
| 
 | ||||
| private: | ||||
|     static ResultVal<std::shared_ptr<ClientSession>> Create(KernelCore& kernel, | ||||
|                                                             std::shared_ptr<Session> parent, | ||||
|  | ||||
| @ -23,6 +23,7 @@ | ||||
| #include "core/hle/kernel/process.h" | ||||
| #include "core/hle/kernel/resource_limit.h" | ||||
| #include "core/hle/kernel/scheduler.h" | ||||
| #include "core/hle/kernel/synchronization.h" | ||||
| #include "core/hle/kernel/thread.h" | ||||
| #include "core/hle/lock.h" | ||||
| #include "core/hle/result.h" | ||||
| @ -96,7 +97,8 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] s64 cycles_ | ||||
| } | ||||
| 
 | ||||
| struct KernelCore::Impl { | ||||
|     explicit Impl(Core::System& system) : system{system}, global_scheduler{system} {} | ||||
|     explicit Impl(Core::System& system) | ||||
|         : system{system}, global_scheduler{system}, synchronization{system} {} | ||||
| 
 | ||||
|     void Initialize(KernelCore& kernel) { | ||||
|         Shutdown(); | ||||
| @ -191,6 +193,7 @@ struct KernelCore::Impl { | ||||
|     std::vector<std::shared_ptr<Process>> process_list; | ||||
|     Process* current_process = nullptr; | ||||
|     Kernel::GlobalScheduler global_scheduler; | ||||
|     Kernel::Synchronization synchronization; | ||||
| 
 | ||||
|     std::shared_ptr<ResourceLimit> system_resource_limit; | ||||
| 
 | ||||
| @ -270,6 +273,14 @@ const Kernel::PhysicalCore& KernelCore::PhysicalCore(std::size_t id) const { | ||||
|     return impl->cores[id]; | ||||
| } | ||||
| 
 | ||||
| Kernel::Synchronization& KernelCore::Synchronization() { | ||||
|     return impl->synchronization; | ||||
| } | ||||
| 
 | ||||
| const Kernel::Synchronization& KernelCore::Synchronization() const { | ||||
|     return impl->synchronization; | ||||
| } | ||||
| 
 | ||||
| Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() { | ||||
|     return *impl->exclusive_monitor; | ||||
| } | ||||
|  | ||||
| @ -29,6 +29,7 @@ class HandleTable; | ||||
| class PhysicalCore; | ||||
| class Process; | ||||
| class ResourceLimit; | ||||
| class Synchronization; | ||||
| class Thread; | ||||
| 
 | ||||
| /// Represents a single instance of the kernel.
 | ||||
| @ -92,6 +93,12 @@ public: | ||||
|     /// Gets the an instance of the respective physical CPU core.
 | ||||
|     const Kernel::PhysicalCore& PhysicalCore(std::size_t id) const; | ||||
| 
 | ||||
|     /// Gets the an instance of the Synchronization Interface.
 | ||||
|     Kernel::Synchronization& Synchronization(); | ||||
| 
 | ||||
|     /// Gets the an instance of the Synchronization Interface.
 | ||||
|     const Kernel::Synchronization& Synchronization() const; | ||||
| 
 | ||||
|     /// Stops execution of 'id' core, in order to reschedule a new thread.
 | ||||
|     void PrepareReschedule(std::size_t id); | ||||
| 
 | ||||
|  | ||||
| @ -357,7 +357,7 @@ void Process::ChangeStatus(ProcessStatus new_status) { | ||||
| 
 | ||||
|     status = new_status; | ||||
|     is_signaled = true; | ||||
|     WakeupAllWaitingThreads(); | ||||
|     Signal(); | ||||
| } | ||||
| 
 | ||||
| void Process::AllocateMainThreadStack(u64 stack_size) { | ||||
|  | ||||
| @ -359,10 +359,6 @@ private: | ||||
|     /// specified by metadata provided to the process during loading.
 | ||||
|     bool is_64bit_process = true; | ||||
| 
 | ||||
|     /// Whether or not this process is signaled. This occurs
 | ||||
|     /// upon the process changing to a different state.
 | ||||
|     bool is_signaled = false; | ||||
| 
 | ||||
|     /// Total running time for the process in ticks.
 | ||||
|     u64 total_process_running_time_ticks = 0; | ||||
| 
 | ||||
|  | ||||
| @ -15,26 +15,26 @@ ReadableEvent::ReadableEvent(KernelCore& kernel) : SynchronizationObject{kernel} | ||||
| ReadableEvent::~ReadableEvent() = default; | ||||
| 
 | ||||
| bool ReadableEvent::ShouldWait(const Thread* thread) const { | ||||
|     return !signaled; | ||||
|     return !is_signaled; | ||||
| } | ||||
| 
 | ||||
| void ReadableEvent::Acquire(Thread* thread) { | ||||
|     ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); | ||||
|     ASSERT_MSG(IsSignaled(), "object unavailable!"); | ||||
| } | ||||
| 
 | ||||
| void ReadableEvent::Signal() { | ||||
|     if (!signaled) { | ||||
|         signaled = true; | ||||
|         WakeupAllWaitingThreads(); | ||||
|     if (!is_signaled) { | ||||
|         is_signaled = true; | ||||
|         SynchronizationObject::Signal(); | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| void ReadableEvent::Clear() { | ||||
|     signaled = false; | ||||
|     is_signaled = false; | ||||
| } | ||||
| 
 | ||||
| ResultCode ReadableEvent::Reset() { | ||||
|     if (!signaled) { | ||||
|     if (!is_signaled) { | ||||
|         return ERR_INVALID_STATE; | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -46,13 +46,11 @@ public: | ||||
|     ///      then ERR_INVALID_STATE will be returned.
 | ||||
|     ResultCode Reset(); | ||||
| 
 | ||||
|     void Signal() override; | ||||
| 
 | ||||
| private: | ||||
|     explicit ReadableEvent(KernelCore& kernel); | ||||
| 
 | ||||
|     void Signal(); | ||||
| 
 | ||||
|     bool signaled{}; | ||||
| 
 | ||||
|     std::string name; ///< Name of event (optional)
 | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -39,6 +39,10 @@ void ServerPort::Acquire(Thread* thread) { | ||||
|     ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); | ||||
| } | ||||
| 
 | ||||
| bool ServerPort::IsSignaled() const { | ||||
|     return !pending_sessions.empty(); | ||||
| } | ||||
| 
 | ||||
| ServerPort::PortPair ServerPort::CreatePortPair(KernelCore& kernel, u32 max_sessions, | ||||
|                                                 std::string name) { | ||||
|     std::shared_ptr<ServerPort> server_port = std::make_shared<ServerPort>(kernel); | ||||
|  | ||||
| @ -82,6 +82,8 @@ public: | ||||
|     bool ShouldWait(const Thread* thread) const override; | ||||
|     void Acquire(Thread* thread) override; | ||||
| 
 | ||||
|     bool IsSignaled() const override; | ||||
| 
 | ||||
| private: | ||||
|     /// ServerSessions waiting to be accepted by the port
 | ||||
|     std::vector<std::shared_ptr<ServerSession>> pending_sessions; | ||||
|  | ||||
| @ -50,6 +50,16 @@ bool ServerSession::ShouldWait(const Thread* thread) const { | ||||
|     return pending_requesting_threads.empty() || currently_handling != nullptr; | ||||
| } | ||||
| 
 | ||||
| bool ServerSession::IsSignaled() const { | ||||
|     // Closed sessions should never wait, an error will be returned from svcReplyAndReceive.
 | ||||
|     if (!parent->Client()) { | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     // Wait if we have no pending requests, or if we're currently handling a request.
 | ||||
|     return !(pending_requesting_threads.empty() || currently_handling != nullptr); | ||||
| } | ||||
| 
 | ||||
| void ServerSession::Acquire(Thread* thread) { | ||||
|     ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); | ||||
|     // We are now handling a request, pop it from the stack.
 | ||||
|  | ||||
| @ -73,6 +73,8 @@ public: | ||||
|         return parent.get(); | ||||
|     } | ||||
| 
 | ||||
|     bool IsSignaled() const override; | ||||
| 
 | ||||
|     /**
 | ||||
|      * Sets the HLE handler for the session. This handler will be called to service IPC requests | ||||
|      * instead of the regular IPC machinery. (The regular IPC machinery is currently not | ||||
|  | ||||
| @ -29,6 +29,11 @@ bool Session::ShouldWait(const Thread* thread) const { | ||||
|     return {}; | ||||
| } | ||||
| 
 | ||||
| bool Session::IsSignaled() const { | ||||
|     UNIMPLEMENTED(); | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| void Session::Acquire(Thread* thread) { | ||||
|     UNIMPLEMENTED(); | ||||
| } | ||||
|  | ||||
| @ -39,6 +39,8 @@ public: | ||||
| 
 | ||||
|     bool ShouldWait(const Thread* thread) const override; | ||||
| 
 | ||||
|     bool IsSignaled() const override; | ||||
| 
 | ||||
|     void Acquire(Thread* thread) override; | ||||
| 
 | ||||
|     std::shared_ptr<ClientSession> Client() { | ||||
|  | ||||
| @ -32,6 +32,7 @@ | ||||
| #include "core/hle/kernel/shared_memory.h" | ||||
| #include "core/hle/kernel/svc.h" | ||||
| #include "core/hle/kernel/svc_wrap.h" | ||||
| #include "core/hle/kernel/synchronization.h" | ||||
| #include "core/hle/kernel/thread.h" | ||||
| #include "core/hle/kernel/transfer_memory.h" | ||||
| #include "core/hle/kernel/writable_event.h" | ||||
| @ -433,23 +434,6 @@ static ResultCode GetProcessId(Core::System& system, u64* process_id, Handle han | ||||
|     return ERR_INVALID_HANDLE; | ||||
| } | ||||
| 
 | ||||
| /// Default thread wakeup callback for WaitSynchronization
 | ||||
| static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, | ||||
|                                         std::shared_ptr<SynchronizationObject> object, | ||||
|                                         std::size_t index) { | ||||
|     ASSERT(thread->GetStatus() == ThreadStatus::WaitSynch); | ||||
| 
 | ||||
|     if (reason == ThreadWakeupReason::Timeout) { | ||||
|         thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     ASSERT(reason == ThreadWakeupReason::Signal); | ||||
|     thread->SetWaitSynchronizationResult(RESULT_SUCCESS); | ||||
|     thread->SetWaitSynchronizationOutput(static_cast<u32>(index)); | ||||
|     return true; | ||||
| }; | ||||
| 
 | ||||
| /// Wait for the given handles to synchronize, timeout after the specified nanoseconds
 | ||||
| static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr handles_address, | ||||
|                                       u64 handle_count, s64 nano_seconds) { | ||||
| @ -473,10 +457,10 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr | ||||
|     } | ||||
| 
 | ||||
|     auto* const thread = system.CurrentScheduler().GetCurrentThread(); | ||||
| 
 | ||||
|     auto& kernel = system.Kernel(); | ||||
|     using ObjectPtr = Thread::ThreadSynchronizationObjects::value_type; | ||||
|     Thread::ThreadSynchronizationObjects objects(handle_count); | ||||
|     const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | ||||
|     const auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); | ||||
| 
 | ||||
|     for (u64 i = 0; i < handle_count; ++i) { | ||||
|         const Handle handle = memory.Read32(handles_address + i * sizeof(Handle)); | ||||
| @ -489,47 +473,10 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr | ||||
| 
 | ||||
|         objects[i] = object; | ||||
|     } | ||||
| 
 | ||||
|     // Find the first object that is acquirable in the provided list of objects
 | ||||
|     auto itr = std::find_if(objects.begin(), objects.end(), [thread](const ObjectPtr& object) { | ||||
|         return !object->ShouldWait(thread); | ||||
|     }); | ||||
| 
 | ||||
|     if (itr != objects.end()) { | ||||
|         // We found a ready object, acquire it and set the result value
 | ||||
|         SynchronizationObject* object = itr->get(); | ||||
|         object->Acquire(thread); | ||||
|         *index = static_cast<s32>(std::distance(objects.begin(), itr)); | ||||
|         return RESULT_SUCCESS; | ||||
|     } | ||||
| 
 | ||||
|     // No objects were ready to be acquired, prepare to suspend the thread.
 | ||||
| 
 | ||||
|     // If a timeout value of 0 was provided, just return the Timeout error code instead of
 | ||||
|     // suspending the thread.
 | ||||
|     if (nano_seconds == 0) { | ||||
|         return RESULT_TIMEOUT; | ||||
|     } | ||||
| 
 | ||||
|     if (thread->IsSyncCancelled()) { | ||||
|         thread->SetSyncCancelled(false); | ||||
|         return ERR_SYNCHRONIZATION_CANCELED; | ||||
|     } | ||||
| 
 | ||||
|     for (auto& object : objects) { | ||||
|         object->AddWaitingThread(SharedFrom(thread)); | ||||
|     } | ||||
| 
 | ||||
|     thread->SetSynchronizationObjects(std::move(objects)); | ||||
|     thread->SetStatus(ThreadStatus::WaitSynch); | ||||
| 
 | ||||
|     // Create an event to wake the thread up after the specified nanosecond delay has passed
 | ||||
|     thread->WakeAfterDelay(nano_seconds); | ||||
|     thread->SetWakeupCallback(DefaultThreadWakeupCallback); | ||||
| 
 | ||||
|     system.PrepareReschedule(thread->GetProcessorID()); | ||||
| 
 | ||||
|     return RESULT_TIMEOUT; | ||||
|     auto& synchronization = kernel.Synchronization(); | ||||
|     auto [result, handle_result] = synchronization.WaitFor(objects, nano_seconds); | ||||
|     *index = handle_result; | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| /// Resumes a thread waiting on WaitSynchronization
 | ||||
|  | ||||
							
								
								
									
										86
									
								
								src/core/hle/kernel/synchronization.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								src/core/hle/kernel/synchronization.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,86 @@ | ||||
| // Copyright 2020 yuzu Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include "core/core.h" | ||||
| #include "core/hle/kernel/errors.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/kernel/scheduler.h" | ||||
| #include "core/hle/kernel/synchronization.h" | ||||
| #include "core/hle/kernel/synchronization_object.h" | ||||
| #include "core/hle/kernel/thread.h" | ||||
| 
 | ||||
| namespace Kernel { | ||||
| 
 | ||||
| /// Default thread wakeup callback for WaitSynchronization
 | ||||
| static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, | ||||
|                                         std::shared_ptr<SynchronizationObject> object, | ||||
|                                         std::size_t index) { | ||||
|     ASSERT(thread->GetStatus() == ThreadStatus::WaitSynch); | ||||
| 
 | ||||
|     if (reason == ThreadWakeupReason::Timeout) { | ||||
|         thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     ASSERT(reason == ThreadWakeupReason::Signal); | ||||
|     thread->SetWaitSynchronizationResult(RESULT_SUCCESS); | ||||
|     thread->SetWaitSynchronizationOutput(static_cast<u32>(index)); | ||||
|     return true; | ||||
| }; | ||||
| 
 | ||||
| Synchronization::Synchronization(Core::System& system) : system{system} {} | ||||
| 
 | ||||
| void Synchronization::SignalObject(SynchronizationObject& obj) const { | ||||
|     if (obj.IsSignaled()) { | ||||
|         obj.WakeupAllWaitingThreads(); | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| std::pair<ResultCode, Handle> Synchronization::WaitFor( | ||||
|     std::vector<std::shared_ptr<SynchronizationObject>>& sync_objects, s64 nano_seconds) { | ||||
|     auto* const thread = system.CurrentScheduler().GetCurrentThread(); | ||||
|     // Find the first object that is acquirable in the provided list of objects
 | ||||
|     auto itr = std::find_if(sync_objects.begin(), sync_objects.end(), | ||||
|                             [thread](const std::shared_ptr<SynchronizationObject>& object) { | ||||
|                                 return object->IsSignaled(); | ||||
|                             }); | ||||
| 
 | ||||
|     if (itr != sync_objects.end()) { | ||||
|         // We found a ready object, acquire it and set the result value
 | ||||
|         SynchronizationObject* object = itr->get(); | ||||
|         object->Acquire(thread); | ||||
|         u32 index = static_cast<s32>(std::distance(sync_objects.begin(), itr)); | ||||
|         return {RESULT_SUCCESS, index}; | ||||
|     } | ||||
| 
 | ||||
|     // No objects were ready to be acquired, prepare to suspend the thread.
 | ||||
| 
 | ||||
|     // If a timeout value of 0 was provided, just return the Timeout error code instead of
 | ||||
|     // suspending the thread.
 | ||||
|     if (nano_seconds == 0) { | ||||
|         return {RESULT_TIMEOUT, 0}; | ||||
|     } | ||||
| 
 | ||||
|     if (thread->IsSyncCancelled()) { | ||||
|         thread->SetSyncCancelled(false); | ||||
|         return {ERR_SYNCHRONIZATION_CANCELED, 0}; | ||||
|     } | ||||
| 
 | ||||
|     for (auto& object : sync_objects) { | ||||
|         object->AddWaitingThread(SharedFrom(thread)); | ||||
|     } | ||||
| 
 | ||||
|     thread->SetSynchronizationObjects(std::move(sync_objects)); | ||||
|     thread->SetStatus(ThreadStatus::WaitSynch); | ||||
| 
 | ||||
|     // Create an event to wake the thread up after the specified nanosecond delay has passed
 | ||||
|     thread->WakeAfterDelay(nano_seconds); | ||||
|     thread->SetWakeupCallback(DefaultThreadWakeupCallback); | ||||
| 
 | ||||
|     system.PrepareReschedule(thread->GetProcessorID()); | ||||
| 
 | ||||
|     return {RESULT_TIMEOUT, 0}; | ||||
| } | ||||
| 
 | ||||
| } // namespace Kernel
 | ||||
							
								
								
									
										34
									
								
								src/core/hle/kernel/synchronization.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/core/hle/kernel/synchronization.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | ||||
| // Copyright 2020 yuzu Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <memory> | ||||
| #include <utility> | ||||
| 
 | ||||
| #include "core/hle/kernel/object.h" | ||||
| #include "core/hle/result.h" | ||||
| 
 | ||||
| namespace Core { | ||||
| class System; | ||||
| } // namespace Core
 | ||||
| 
 | ||||
| namespace Kernel { | ||||
| 
 | ||||
| class KernelCore; | ||||
| class SynchronizationObject; | ||||
| 
 | ||||
| class Synchronization { | ||||
| public: | ||||
|     Synchronization(Core::System& system); | ||||
| 
 | ||||
|     void SignalObject(SynchronizationObject& obj) const; | ||||
| 
 | ||||
|     std::pair<ResultCode, Handle> WaitFor( | ||||
|         std::vector<std::shared_ptr<SynchronizationObject>>& sync_objects, s64 nano_seconds); | ||||
| 
 | ||||
| private: | ||||
|     Core::System& system; | ||||
| }; | ||||
| } // namespace Kernel
 | ||||
| @ -10,6 +10,7 @@ | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/kernel/object.h" | ||||
| #include "core/hle/kernel/process.h" | ||||
| #include "core/hle/kernel/synchronization.h" | ||||
| #include "core/hle/kernel/synchronization_object.h" | ||||
| #include "core/hle/kernel/thread.h" | ||||
| 
 | ||||
| @ -18,6 +19,10 @@ namespace Kernel { | ||||
| SynchronizationObject::SynchronizationObject(KernelCore& kernel) : Object{kernel} {} | ||||
| SynchronizationObject::~SynchronizationObject() = default; | ||||
| 
 | ||||
| void SynchronizationObject::Signal() { | ||||
|     kernel.Synchronization().SignalObject(*this); | ||||
| } | ||||
| 
 | ||||
| void SynchronizationObject::AddWaitingThread(std::shared_ptr<Thread> thread) { | ||||
|     auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread); | ||||
|     if (itr == waiting_threads.end()) | ||||
|  | ||||
| @ -30,6 +30,13 @@ public: | ||||
|     /// Acquire/lock the object for the specified thread if it is available
 | ||||
|     virtual void Acquire(Thread* thread) = 0; | ||||
| 
 | ||||
|     /// Signal this object
 | ||||
|     virtual void Signal(); | ||||
| 
 | ||||
|     virtual bool IsSignaled() const { | ||||
|         return is_signaled; | ||||
|     } | ||||
| 
 | ||||
|     /**
 | ||||
|      * Add a thread to wait on this object | ||||
|      * @param thread Pointer to thread to add | ||||
| @ -60,6 +67,9 @@ public: | ||||
|     /// Get a const reference to the waiting threads list for debug use
 | ||||
|     const std::vector<std::shared_ptr<Thread>>& GetWaitingThreads() const; | ||||
| 
 | ||||
| protected: | ||||
|     bool is_signaled{}; // Tells if this sync object is signalled;
 | ||||
| 
 | ||||
| private: | ||||
|     /// Threads waiting for this object to become available
 | ||||
|     std::vector<std::shared_ptr<Thread>> waiting_threads; | ||||
|  | ||||
| @ -31,6 +31,10 @@ bool Thread::ShouldWait(const Thread* thread) const { | ||||
|     return status != ThreadStatus::Dead; | ||||
| } | ||||
| 
 | ||||
| bool Thread::IsSignaled() const { | ||||
|     return status == ThreadStatus::Dead; | ||||
| } | ||||
| 
 | ||||
| void Thread::Acquire(Thread* thread) { | ||||
|     ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); | ||||
| } | ||||
| @ -45,7 +49,7 @@ void Thread::Stop() { | ||||
|     kernel.ThreadWakeupCallbackHandleTable().Close(callback_handle); | ||||
|     callback_handle = 0; | ||||
|     SetStatus(ThreadStatus::Dead); | ||||
|     WakeupAllWaitingThreads(); | ||||
|     Signal(); | ||||
| 
 | ||||
|     // Clean up any dangling references in objects that this thread was waiting for
 | ||||
|     for (auto& wait_object : wait_objects) { | ||||
|  | ||||
| @ -146,6 +146,7 @@ public: | ||||
| 
 | ||||
|     bool ShouldWait(const Thread* thread) const override; | ||||
|     void Acquire(Thread* thread) override; | ||||
|     bool IsSignaled() const override; | ||||
| 
 | ||||
|     /**
 | ||||
|      * Gets the thread's current priority | ||||
|  | ||||
| @ -22,7 +22,6 @@ EventPair WritableEvent::CreateEventPair(KernelCore& kernel, std::string name) { | ||||
|     writable_event->name = name + ":Writable"; | ||||
|     writable_event->readable = readable_event; | ||||
|     readable_event->name = name + ":Readable"; | ||||
|     readable_event->signaled = false; | ||||
| 
 | ||||
|     return {std::move(readable_event), std::move(writable_event)}; | ||||
| } | ||||
| @ -40,7 +39,7 @@ void WritableEvent::Clear() { | ||||
| } | ||||
| 
 | ||||
| bool WritableEvent::IsSignaled() const { | ||||
|     return readable->signaled; | ||||
|     return readable->IsSignaled(); | ||||
| } | ||||
| 
 | ||||
| } // namespace Kernel
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Fernando Sahmkow
						Fernando Sahmkow