Browse Source

core: hle: kernel: Update KSynchronizationObject.

bunnei 5 years ago
parent
commit
35c3c078e3

+ 2 - 4
src/core/CMakeLists.txt

@@ -164,6 +164,8 @@ add_library(core STATIC
     hle/kernel/k_scheduler_lock.h
     hle/kernel/k_scheduler_lock.h
     hle/kernel/k_scoped_lock.h
     hle/kernel/k_scoped_lock.h
     hle/kernel/k_scoped_scheduler_lock_and_sleep.h
     hle/kernel/k_scoped_scheduler_lock_and_sleep.h
+    hle/kernel/k_synchronization_object.cpp
+    hle/kernel/k_synchronization_object.h
     hle/kernel/kernel.cpp
     hle/kernel/kernel.cpp
     hle/kernel/kernel.h
     hle/kernel/kernel.h
     hle/kernel/memory/address_space_info.cpp
     hle/kernel/memory/address_space_info.cpp
@@ -213,10 +215,6 @@ add_library(core STATIC
     hle/kernel/svc_results.h
     hle/kernel/svc_results.h
     hle/kernel/svc_types.h
     hle/kernel/svc_types.h
     hle/kernel/svc_wrap.h
     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.cpp
     hle/kernel/thread.h
     hle/kernel/thread.h
     hle/kernel/time_manager.cpp
     hle/kernel/time_manager.cpp

+ 5 - 5
src/core/hle/kernel/address_arbiter.cpp

@@ -37,7 +37,7 @@ void AddressArbiter::WakeThreads(const std::vector<std::shared_ptr<Thread>>& wai
         waiting_threads[i]->SetSynchronizationResults(nullptr, RESULT_SUCCESS);
         waiting_threads[i]->SetSynchronizationResults(nullptr, RESULT_SUCCESS);
         RemoveThread(waiting_threads[i]);
         RemoveThread(waiting_threads[i]);
         waiting_threads[i]->WaitForArbitration(false);
         waiting_threads[i]->WaitForArbitration(false);
-        waiting_threads[i]->ResumeFromWait();
+        waiting_threads[i]->Wakeup();
     }
     }
 }
 }
 
 
@@ -160,7 +160,7 @@ ResultCode AddressArbiter::WaitForAddressIfLessThan(VAddr address, s32 value, s6
     {
     {
         KScopedSchedulerLockAndSleep lock(kernel, event_handle, current_thread, timeout);
         KScopedSchedulerLockAndSleep lock(kernel, event_handle, current_thread, timeout);
 
 
-        if (current_thread->IsPendingTermination()) {
+        if (current_thread->IsTerminationRequested()) {
             lock.CancelSleep();
             lock.CancelSleep();
             return ERR_THREAD_TERMINATING;
             return ERR_THREAD_TERMINATING;
         }
         }
@@ -201,7 +201,7 @@ ResultCode AddressArbiter::WaitForAddressIfLessThan(VAddr address, s32 value, s6
 
 
         current_thread->SetArbiterWaitAddress(address);
         current_thread->SetArbiterWaitAddress(address);
         InsertThread(SharedFrom(current_thread));
         InsertThread(SharedFrom(current_thread));
-        current_thread->SetStatus(ThreadStatus::WaitArb);
+        current_thread->SetState(ThreadStatus::WaitArb);
         current_thread->WaitForArbitration(true);
         current_thread->WaitForArbitration(true);
     }
     }
 
 
@@ -230,7 +230,7 @@ ResultCode AddressArbiter::WaitForAddressIfEqual(VAddr address, s32 value, s64 t
     {
     {
         KScopedSchedulerLockAndSleep lock(kernel, event_handle, current_thread, timeout);
         KScopedSchedulerLockAndSleep lock(kernel, event_handle, current_thread, timeout);
 
 
-        if (current_thread->IsPendingTermination()) {
+        if (current_thread->IsTerminationRequested()) {
             lock.CancelSleep();
             lock.CancelSleep();
             return ERR_THREAD_TERMINATING;
             return ERR_THREAD_TERMINATING;
         }
         }
@@ -256,7 +256,7 @@ ResultCode AddressArbiter::WaitForAddressIfEqual(VAddr address, s32 value, s64 t
         current_thread->SetSynchronizationResults(nullptr, RESULT_TIMEOUT);
         current_thread->SetSynchronizationResults(nullptr, RESULT_TIMEOUT);
         current_thread->SetArbiterWaitAddress(address);
         current_thread->SetArbiterWaitAddress(address);
         InsertThread(SharedFrom(current_thread));
         InsertThread(SharedFrom(current_thread));
-        current_thread->SetStatus(ThreadStatus::WaitArb);
+        current_thread->SetState(ThreadStatus::WaitArb);
         current_thread->WaitForArbitration(true);
         current_thread->WaitForArbitration(true);
     }
     }
 
 

+ 0 - 3
src/core/hle/kernel/client_port.cpp

@@ -33,9 +33,6 @@ ResultVal<std::shared_ptr<ClientSession>> ClientPort::Connect() {
         server_port->AppendPendingSession(std::move(server));
         server_port->AppendPendingSession(std::move(server));
     }
     }
 
 
-    // Wake the threads waiting on the ServerPort
-    server_port->Signal();
-
     return MakeResult(std::move(client));
     return MakeResult(std::move(client));
 }
 }
 
 

+ 1 - 10
src/core/hle/kernel/client_session.cpp

@@ -12,7 +12,7 @@
 
 
 namespace Kernel {
 namespace Kernel {
 
 
-ClientSession::ClientSession(KernelCore& kernel) : SynchronizationObject{kernel} {}
+ClientSession::ClientSession(KernelCore& kernel) : KSynchronizationObject{kernel} {}
 
 
 ClientSession::~ClientSession() {
 ClientSession::~ClientSession() {
     // This destructor will be called automatically when the last ClientSession handle is closed by
     // This destructor will be called automatically when the last ClientSession handle is closed by
@@ -22,15 +22,6 @@ ClientSession::~ClientSession() {
     }
     }
 }
 }
 
 
-bool ClientSession::ShouldWait(const Thread* thread) const {
-    UNIMPLEMENTED();
-    return {};
-}
-
-void ClientSession::Acquire(Thread* thread) {
-    UNIMPLEMENTED();
-}
-
 bool ClientSession::IsSignaled() const {
 bool ClientSession::IsSignaled() const {
     UNIMPLEMENTED();
     UNIMPLEMENTED();
     return true;
     return true;

+ 2 - 6
src/core/hle/kernel/client_session.h

@@ -7,7 +7,7 @@
 #include <memory>
 #include <memory>
 #include <string>
 #include <string>
 
 
-#include "core/hle/kernel/synchronization_object.h"
+#include "core/hle/kernel/k_synchronization_object.h"
 #include "core/hle/result.h"
 #include "core/hle/result.h"
 
 
 union ResultCode;
 union ResultCode;
@@ -26,7 +26,7 @@ class KernelCore;
 class Session;
 class Session;
 class Thread;
 class Thread;
 
 
-class ClientSession final : public SynchronizationObject {
+class ClientSession final : public KSynchronizationObject {
 public:
 public:
     explicit ClientSession(KernelCore& kernel);
     explicit ClientSession(KernelCore& kernel);
     ~ClientSession() override;
     ~ClientSession() override;
@@ -49,10 +49,6 @@ public:
     ResultCode SendSyncRequest(std::shared_ptr<Thread> thread, Core::Memory::Memory& memory,
     ResultCode SendSyncRequest(std::shared_ptr<Thread> thread, Core::Memory::Memory& memory,
                                Core::Timing::CoreTiming& core_timing);
                                Core::Timing::CoreTiming& core_timing);
 
 
-    bool ShouldWait(const Thread* thread) const override;
-
-    void Acquire(Thread* thread) override;
-
     bool IsSignaled() const override;
     bool IsSignaled() const override;
 
 
 private:
 private:

+ 3 - 0
src/core/hle/kernel/errors.h

@@ -13,12 +13,14 @@ namespace Kernel {
 constexpr ResultCode ERR_MAX_CONNECTIONS_REACHED{ErrorModule::Kernel, 7};
 constexpr ResultCode ERR_MAX_CONNECTIONS_REACHED{ErrorModule::Kernel, 7};
 constexpr ResultCode ERR_INVALID_CAPABILITY_DESCRIPTOR{ErrorModule::Kernel, 14};
 constexpr ResultCode ERR_INVALID_CAPABILITY_DESCRIPTOR{ErrorModule::Kernel, 14};
 constexpr ResultCode ERR_THREAD_TERMINATING{ErrorModule::Kernel, 59};
 constexpr ResultCode ERR_THREAD_TERMINATING{ErrorModule::Kernel, 59};
+constexpr ResultCode ERR_TERMINATION_REQUESTED{ErrorModule::Kernel, 59};
 constexpr ResultCode ERR_INVALID_SIZE{ErrorModule::Kernel, 101};
 constexpr ResultCode ERR_INVALID_SIZE{ErrorModule::Kernel, 101};
 constexpr ResultCode ERR_INVALID_ADDRESS{ErrorModule::Kernel, 102};
 constexpr ResultCode ERR_INVALID_ADDRESS{ErrorModule::Kernel, 102};
 constexpr ResultCode ERR_OUT_OF_RESOURCES{ErrorModule::Kernel, 103};
 constexpr ResultCode ERR_OUT_OF_RESOURCES{ErrorModule::Kernel, 103};
 constexpr ResultCode ERR_OUT_OF_MEMORY{ErrorModule::Kernel, 104};
 constexpr ResultCode ERR_OUT_OF_MEMORY{ErrorModule::Kernel, 104};
 constexpr ResultCode ERR_HANDLE_TABLE_FULL{ErrorModule::Kernel, 105};
 constexpr ResultCode ERR_HANDLE_TABLE_FULL{ErrorModule::Kernel, 105};
 constexpr ResultCode ERR_INVALID_ADDRESS_STATE{ErrorModule::Kernel, 106};
 constexpr ResultCode ERR_INVALID_ADDRESS_STATE{ErrorModule::Kernel, 106};
+constexpr ResultCode ERR_INVALID_CURRENT_MEMORY{ErrorModule::Kernel, 106};
 constexpr ResultCode ERR_INVALID_MEMORY_PERMISSIONS{ErrorModule::Kernel, 108};
 constexpr ResultCode ERR_INVALID_MEMORY_PERMISSIONS{ErrorModule::Kernel, 108};
 constexpr ResultCode ERR_INVALID_MEMORY_RANGE{ErrorModule::Kernel, 110};
 constexpr ResultCode ERR_INVALID_MEMORY_RANGE{ErrorModule::Kernel, 110};
 constexpr ResultCode ERR_INVALID_PROCESSOR_ID{ErrorModule::Kernel, 113};
 constexpr ResultCode ERR_INVALID_PROCESSOR_ID{ErrorModule::Kernel, 113};
@@ -28,6 +30,7 @@ constexpr ResultCode ERR_INVALID_POINTER{ErrorModule::Kernel, 115};
 constexpr ResultCode ERR_INVALID_COMBINATION{ErrorModule::Kernel, 116};
 constexpr ResultCode ERR_INVALID_COMBINATION{ErrorModule::Kernel, 116};
 constexpr ResultCode RESULT_TIMEOUT{ErrorModule::Kernel, 117};
 constexpr ResultCode RESULT_TIMEOUT{ErrorModule::Kernel, 117};
 constexpr ResultCode ERR_SYNCHRONIZATION_CANCELED{ErrorModule::Kernel, 118};
 constexpr ResultCode ERR_SYNCHRONIZATION_CANCELED{ErrorModule::Kernel, 118};
+constexpr ResultCode ERR_CANCELLED{ErrorModule::Kernel, 118};
 constexpr ResultCode ERR_OUT_OF_RANGE{ErrorModule::Kernel, 119};
 constexpr ResultCode ERR_OUT_OF_RANGE{ErrorModule::Kernel, 119};
 constexpr ResultCode ERR_INVALID_ENUM_VALUE{ErrorModule::Kernel, 120};
 constexpr ResultCode ERR_INVALID_ENUM_VALUE{ErrorModule::Kernel, 120};
 constexpr ResultCode ERR_NOT_FOUND{ErrorModule::Kernel, 121};
 constexpr ResultCode ERR_NOT_FOUND{ErrorModule::Kernel, 121};

+ 2 - 3
src/core/hle/kernel/k_scheduler.cpp

@@ -645,8 +645,7 @@ void KScheduler::Unload(Thread* thread) {
 
 
 void KScheduler::Reload(Thread* thread) {
 void KScheduler::Reload(Thread* thread) {
     if (thread) {
     if (thread) {
-        ASSERT_MSG(thread->GetSchedulingStatus() == ThreadSchedStatus::Runnable,
-                   "Thread must be runnable.");
+        ASSERT_MSG(thread->GetState() == ThreadSchedStatus::Runnable, "Thread must be runnable.");
 
 
         // Cancel any outstanding wakeup events for this thread
         // Cancel any outstanding wakeup events for this thread
         thread->SetIsRunning(true);
         thread->SetIsRunning(true);
@@ -772,7 +771,7 @@ void KScheduler::Initialize() {
 
 
     {
     {
         KScopedSchedulerLock lock{system.Kernel()};
         KScopedSchedulerLock lock{system.Kernel()};
-        idle_thread->SetStatus(ThreadStatus::Ready);
+        idle_thread->SetState(ThreadStatus::Ready);
     }
     }
 }
 }
 
 

+ 171 - 0
src/core/hle/kernel/k_synchronization_object.cpp

@@ -0,0 +1,171 @@
+// Copyright 2021 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/assert.h"
+#include "common/common_types.h"
+#include "core/hle/kernel/k_scheduler.h"
+#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
+#include "core/hle/kernel/k_synchronization_object.h"
+#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/svc_results.h"
+#include "core/hle/kernel/thread.h"
+
+namespace Kernel {
+
+ResultCode KSynchronizationObject::Wait(KernelCore& kernel, s32* out_index,
+                                        KSynchronizationObject** objects, const s32 num_objects,
+                                        s64 timeout) {
+    // Allocate space on stack for thread nodes.
+    std::vector<ThreadListNode> thread_nodes(num_objects);
+
+    // Prepare for wait.
+    Thread* thread = kernel.CurrentScheduler()->GetCurrentThread();
+    Handle timer = InvalidHandle;
+
+    {
+        // Setup the scheduling lock and sleep.
+        KScopedSchedulerLockAndSleep slp(kernel, timer, thread, timeout);
+
+        // Check if any of the objects are already signaled.
+        for (auto i = 0; i < num_objects; ++i) {
+            ASSERT(objects[i] != nullptr);
+
+            if (objects[i]->IsSignaled()) {
+                *out_index = i;
+                slp.CancelSleep();
+                return RESULT_SUCCESS;
+            }
+        }
+
+        // Check if the timeout is zero.
+        if (timeout == 0) {
+            slp.CancelSleep();
+            return Svc::ResultTimedOut;
+        }
+
+        // Check if the thread should terminate.
+        if (thread->IsTerminationRequested()) {
+            slp.CancelSleep();
+            return Svc::ResultTerminationRequested;
+        }
+
+        // Check if waiting was canceled.
+        if (thread->IsWaitCancelled()) {
+            slp.CancelSleep();
+            thread->ClearWaitCancelled();
+            return Svc::ResultCancelled;
+        }
+
+        // Add the waiters.
+        for (auto i = 0; i < num_objects; ++i) {
+            thread_nodes[i].thread = thread;
+            thread_nodes[i].next = nullptr;
+
+            if (objects[i]->thread_list_tail == nullptr) {
+                objects[i]->thread_list_head = std::addressof(thread_nodes[i]);
+            } else {
+                objects[i]->thread_list_tail->next = std::addressof(thread_nodes[i]);
+            }
+
+            objects[i]->thread_list_tail = std::addressof(thread_nodes[i]);
+        }
+
+        // For debugging only
+        thread->SetWaitObjectsForDebugging(objects, num_objects);
+
+        // Mark the thread as waiting.
+        thread->SetCancellable();
+        thread->SetSyncedObject(nullptr, Svc::ResultTimedOut);
+        thread->SetState(ThreadState::WaitSynch);
+    }
+
+    // The lock/sleep is done, so we should be able to get our result.
+
+    // Thread is no longer cancellable.
+    thread->ClearCancellable();
+
+    // For debugging only
+    thread->SetWaitObjectsForDebugging(nullptr, 0);
+
+    // Cancel the timer as needed.
+    if (timer != InvalidHandle) {
+        auto& time_manager = kernel.TimeManager();
+        time_manager.UnscheduleTimeEvent(timer);
+    }
+
+    // Get the wait result.
+    ResultCode wait_result{RESULT_SUCCESS};
+    s32 sync_index = -1;
+    {
+        KScopedSchedulerLock lock(kernel);
+        KSynchronizationObject* synced_obj;
+        wait_result = thread->GetWaitResult(std::addressof(synced_obj));
+
+        for (auto i = 0; i < num_objects; ++i) {
+            // Unlink the object from the list.
+            ThreadListNode* prev_ptr =
+                reinterpret_cast<ThreadListNode*>(std::addressof(objects[i]->thread_list_head));
+            ThreadListNode* prev_val = nullptr;
+            ThreadListNode *prev, *tail_prev;
+
+            do {
+                prev = prev_ptr;
+                prev_ptr = prev_ptr->next;
+                tail_prev = prev_val;
+                prev_val = prev_ptr;
+            } while (prev_ptr != std::addressof(thread_nodes[i]));
+
+            if (objects[i]->thread_list_tail == std::addressof(thread_nodes[i])) {
+                objects[i]->thread_list_tail = tail_prev;
+            }
+
+            prev->next = thread_nodes[i].next;
+
+            if (objects[i] == synced_obj) {
+                sync_index = i;
+            }
+        }
+    }
+
+    // Set output.
+    *out_index = sync_index;
+    return wait_result;
+}
+
+KSynchronizationObject::KSynchronizationObject(KernelCore& kernel) : Object{kernel} {}
+
+KSynchronizationObject ::~KSynchronizationObject() = default;
+
+void KSynchronizationObject::NotifyAvailable(ResultCode result) {
+    KScopedSchedulerLock lock(kernel);
+
+    // If we're not signaled, we've nothing to notify.
+    if (!this->IsSignaled()) {
+        return;
+    }
+
+    // Iterate over each thread.
+    for (auto* cur_node = thread_list_head; cur_node != nullptr; cur_node = cur_node->next) {
+        Thread* thread = cur_node->thread;
+        if (thread->GetState() == ThreadSchedStatus::Paused) {
+            thread->SetSyncedObject(this, result);
+            thread->SetState(ThreadStatus::Ready);
+        }
+    }
+}
+
+std::vector<Thread*> KSynchronizationObject::GetWaitingThreadsForDebugging() const {
+    std::vector<Thread*> threads;
+
+    // If debugging, dump the list of waiters.
+    {
+        KScopedSchedulerLock lock(kernel);
+        for (auto* cur_node = thread_list_head; cur_node != nullptr; cur_node = cur_node->next) {
+            threads.emplace_back(cur_node->thread);
+        }
+    }
+
+    return threads;
+}
+} // namespace Kernel

+ 58 - 0
src/core/hle/kernel/k_synchronization_object.h

@@ -0,0 +1,58 @@
+// Copyright 2021 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <vector>
+
+#include "core/hle/kernel/object.h"
+#include "core/hle/result.h"
+
+namespace Kernel {
+
+class KernelCore;
+class Synchronization;
+class Thread;
+
+/// Class that represents a Kernel object that a thread can be waiting on
+class KSynchronizationObject : public Object {
+public:
+    struct ThreadListNode {
+        ThreadListNode* next{};
+        Thread* thread{};
+    };
+
+    [[nodiscard]] static ResultCode Wait(KernelCore& kernel, s32* out_index,
+                                         KSynchronizationObject** objects, const s32 num_objects,
+                                         s64 timeout);
+
+    [[nodiscard]] virtual bool IsSignaled() const = 0;
+
+    [[nodiscard]] std::vector<Thread*> GetWaitingThreadsForDebugging() const;
+
+protected:
+    explicit KSynchronizationObject(KernelCore& kernel);
+    virtual ~KSynchronizationObject();
+
+    void NotifyAvailable(ResultCode result);
+    void NotifyAvailable() {
+        return this->NotifyAvailable(RESULT_SUCCESS);
+    }
+
+private:
+    ThreadListNode* thread_list_head{};
+    ThreadListNode* thread_list_tail{};
+};
+
+// Specialization of DynamicObjectCast for KSynchronizationObjects
+template <>
+inline std::shared_ptr<KSynchronizationObject> DynamicObjectCast<KSynchronizationObject>(
+    std::shared_ptr<Object> object) {
+    if (object != nullptr && object->IsWaitable()) {
+        return std::static_pointer_cast<KSynchronizationObject>(object);
+    }
+    return nullptr;
+}
+
+} // namespace Kernel

+ 2 - 13
src/core/hle/kernel/kernel.cpp

@@ -38,7 +38,6 @@
 #include "core/hle/kernel/resource_limit.h"
 #include "core/hle/kernel/resource_limit.h"
 #include "core/hle/kernel/service_thread.h"
 #include "core/hle/kernel/service_thread.h"
 #include "core/hle/kernel/shared_memory.h"
 #include "core/hle/kernel/shared_memory.h"
-#include "core/hle/kernel/synchronization.h"
 #include "core/hle/kernel/thread.h"
 #include "core/hle/kernel/thread.h"
 #include "core/hle/kernel/time_manager.h"
 #include "core/hle/kernel/time_manager.h"
 #include "core/hle/lock.h"
 #include "core/hle/lock.h"
@@ -51,8 +50,7 @@ namespace Kernel {
 
 
 struct KernelCore::Impl {
 struct KernelCore::Impl {
     explicit Impl(Core::System& system, KernelCore& kernel)
     explicit Impl(Core::System& system, KernelCore& kernel)
-        : synchronization{system}, time_manager{system}, global_handle_table{kernel}, system{
-                                                                                          system} {}
+        : time_manager{system}, global_handle_table{kernel}, system{system} {}
 
 
     void SetMulticore(bool is_multicore) {
     void SetMulticore(bool is_multicore) {
         this->is_multicore = is_multicore;
         this->is_multicore = is_multicore;
@@ -307,7 +305,6 @@ struct KernelCore::Impl {
     std::vector<std::shared_ptr<Process>> process_list;
     std::vector<std::shared_ptr<Process>> process_list;
     Process* current_process = nullptr;
     Process* current_process = nullptr;
     std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context;
     std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context;
-    Kernel::Synchronization synchronization;
     Kernel::TimeManager time_manager;
     Kernel::TimeManager time_manager;
 
 
     std::shared_ptr<ResourceLimit> system_resource_limit;
     std::shared_ptr<ResourceLimit> system_resource_limit;
@@ -461,14 +458,6 @@ const std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& Kern
     return impl->interrupts;
     return impl->interrupts;
 }
 }
 
 
-Kernel::Synchronization& KernelCore::Synchronization() {
-    return impl->synchronization;
-}
-
-const Kernel::Synchronization& KernelCore::Synchronization() const {
-    return impl->synchronization;
-}
-
 Kernel::TimeManager& KernelCore::TimeManager() {
 Kernel::TimeManager& KernelCore::TimeManager() {
     return impl->time_manager;
     return impl->time_manager;
 }
 }
@@ -615,7 +604,7 @@ void KernelCore::Suspend(bool in_suspention) {
         KScopedSchedulerLock lock(*this);
         KScopedSchedulerLock lock(*this);
         ThreadStatus status = should_suspend ? ThreadStatus::Ready : ThreadStatus::WaitSleep;
         ThreadStatus status = should_suspend ? ThreadStatus::Ready : ThreadStatus::WaitSleep;
         for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
         for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
-            impl->suspend_threads[i]->SetStatus(status);
+            impl->suspend_threads[i]->SetState(status);
         }
         }
     }
     }
 }
 }

+ 0 - 6
src/core/hle/kernel/kernel.h

@@ -129,12 +129,6 @@ public:
     /// Gets the an instance of the current physical CPU core.
     /// Gets the an instance of the current physical CPU core.
     const Kernel::PhysicalCore& CurrentPhysicalCore() const;
     const Kernel::PhysicalCore& CurrentPhysicalCore() 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;
-
     /// Gets the an instance of the TimeManager Interface.
     /// Gets the an instance of the TimeManager Interface.
     Kernel::TimeManager& TimeManager();
     Kernel::TimeManager& TimeManager();
 
 

+ 2 - 2
src/core/hle/kernel/mutex.cpp

@@ -107,7 +107,7 @@ ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle,
         current_thread->SetMutexWaitAddress(address);
         current_thread->SetMutexWaitAddress(address);
         current_thread->SetWaitHandle(requesting_thread_handle);
         current_thread->SetWaitHandle(requesting_thread_handle);
 
 
-        current_thread->SetStatus(ThreadStatus::WaitMutex);
+        current_thread->SetState(ThreadStatus::WaitMutex);
 
 
         // Update the lock holder thread's priority to prevent priority inversion.
         // Update the lock holder thread's priority to prevent priority inversion.
         holding_thread->AddMutexWaiter(current_thread);
         holding_thread->AddMutexWaiter(current_thread);
@@ -145,7 +145,7 @@ std::pair<ResultCode, std::shared_ptr<Thread>> Mutex::Unlock(std::shared_ptr<Thr
     }
     }
     new_owner->SetSynchronizationResults(nullptr, RESULT_SUCCESS);
     new_owner->SetSynchronizationResults(nullptr, RESULT_SUCCESS);
     new_owner->SetLockOwner(nullptr);
     new_owner->SetLockOwner(nullptr);
-    new_owner->ResumeFromWait();
+    new_owner->Wakeup();
 
 
     system.Memory().Write32(address, mutex_value);
     system.Memory().Write32(address, mutex_value);
     return {RESULT_SUCCESS, new_owner};
     return {RESULT_SUCCESS, new_owner};

+ 9 - 12
src/core/hle/kernel/process.cpp

@@ -55,7 +55,7 @@ void SetupMainThread(Core::System& system, Process& owner_process, u32 priority,
     // Threads by default are dormant, wake up the main thread so it runs when the scheduler fires
     // Threads by default are dormant, wake up the main thread so it runs when the scheduler fires
     {
     {
         KScopedSchedulerLock lock{kernel};
         KScopedSchedulerLock lock{kernel};
-        thread->SetStatus(ThreadStatus::Ready);
+        thread->SetState(ThreadStatus::Ready);
     }
     }
 }
 }
 } // Anonymous namespace
 } // Anonymous namespace
@@ -406,21 +406,18 @@ void Process::LoadModule(CodeSet code_set, VAddr base_addr) {
     ReprotectSegment(code_set.DataSegment(), Memory::MemoryPermission::ReadAndWrite);
     ReprotectSegment(code_set.DataSegment(), Memory::MemoryPermission::ReadAndWrite);
 }
 }
 
 
+bool Process::IsSignaled() const {
+    ASSERT(kernel.GlobalSchedulerContext().IsLocked());
+    return is_signaled;
+}
+
 Process::Process(Core::System& system)
 Process::Process(Core::System& system)
-    : SynchronizationObject{system.Kernel()}, page_table{std::make_unique<Memory::PageTable>(
-                                                  system)},
+    : KSynchronizationObject{system.Kernel()}, page_table{std::make_unique<Memory::PageTable>(
+                                                   system)},
       handle_table{system.Kernel()}, address_arbiter{system}, mutex{system}, system{system} {}
       handle_table{system.Kernel()}, address_arbiter{system}, mutex{system}, system{system} {}
 
 
 Process::~Process() = default;
 Process::~Process() = default;
 
 
-void Process::Acquire(Thread* thread) {
-    ASSERT_MSG(!ShouldWait(thread), "Object unavailable!");
-}
-
-bool Process::ShouldWait(const Thread* thread) const {
-    return !is_signaled;
-}
-
 void Process::ChangeStatus(ProcessStatus new_status) {
 void Process::ChangeStatus(ProcessStatus new_status) {
     if (status == new_status) {
     if (status == new_status) {
         return;
         return;
@@ -428,7 +425,7 @@ void Process::ChangeStatus(ProcessStatus new_status) {
 
 
     status = new_status;
     status = new_status;
     is_signaled = true;
     is_signaled = true;
-    Signal();
+    NotifyAvailable();
 }
 }
 
 
 ResultCode Process::AllocateMainThreadStack(std::size_t stack_size) {
 ResultCode Process::AllocateMainThreadStack(std::size_t stack_size) {

+ 6 - 8
src/core/hle/kernel/process.h

@@ -13,9 +13,9 @@
 #include "common/common_types.h"
 #include "common/common_types.h"
 #include "core/hle/kernel/address_arbiter.h"
 #include "core/hle/kernel/address_arbiter.h"
 #include "core/hle/kernel/handle_table.h"
 #include "core/hle/kernel/handle_table.h"
+#include "core/hle/kernel/k_synchronization_object.h"
 #include "core/hle/kernel/mutex.h"
 #include "core/hle/kernel/mutex.h"
 #include "core/hle/kernel/process_capability.h"
 #include "core/hle/kernel/process_capability.h"
-#include "core/hle/kernel/synchronization_object.h"
 #include "core/hle/result.h"
 #include "core/hle/result.h"
 
 
 namespace Core {
 namespace Core {
@@ -63,7 +63,7 @@ enum class ProcessStatus {
     DebugBreak,
     DebugBreak,
 };
 };
 
 
-class Process final : public SynchronizationObject {
+class Process final : public KSynchronizationObject {
 public:
 public:
     explicit Process(Core::System& system);
     explicit Process(Core::System& system);
     ~Process() override;
     ~Process() override;
@@ -304,6 +304,8 @@ public:
 
 
     void LoadModule(CodeSet code_set, VAddr base_addr);
     void LoadModule(CodeSet code_set, VAddr base_addr);
 
 
+    bool IsSignaled() const override;
+
     ///////////////////////////////////////////////////////////////////////////////////////////////
     ///////////////////////////////////////////////////////////////////////////////////////////////
     // Thread-local storage management
     // Thread-local storage management
 
 
@@ -314,12 +316,6 @@ public:
     void FreeTLSRegion(VAddr tls_address);
     void FreeTLSRegion(VAddr tls_address);
 
 
 private:
 private:
-    /// Checks if the specified thread should wait until this process is available.
-    bool ShouldWait(const Thread* thread) const override;
-
-    /// Acquires/locks this process for the specified thread if it's available.
-    void Acquire(Thread* thread) override;
-
     /// Changes the process status. If the status is different
     /// Changes the process status. If the status is different
     /// from the current process status, then this will trigger
     /// from the current process status, then this will trigger
     /// a process signal.
     /// a process signal.
@@ -410,6 +406,8 @@ private:
     /// Schedule count of this process
     /// Schedule count of this process
     s64 schedule_count{};
     s64 schedule_count{};
 
 
+    bool is_signaled{};
+
     /// System context
     /// System context
     Core::System& system;
     Core::System& system;
 };
 };

+ 8 - 10
src/core/hle/kernel/readable_event.cpp

@@ -14,24 +14,22 @@
 
 
 namespace Kernel {
 namespace Kernel {
 
 
-ReadableEvent::ReadableEvent(KernelCore& kernel) : SynchronizationObject{kernel} {}
+ReadableEvent::ReadableEvent(KernelCore& kernel) : KSynchronizationObject{kernel} {}
 ReadableEvent::~ReadableEvent() = default;
 ReadableEvent::~ReadableEvent() = default;
 
 
-bool ReadableEvent::ShouldWait(const Thread* thread) const {
-    return !is_signaled;
-}
-
-void ReadableEvent::Acquire(Thread* thread) {
-    ASSERT_MSG(IsSignaled(), "object unavailable!");
-}
-
 void ReadableEvent::Signal() {
 void ReadableEvent::Signal() {
     if (is_signaled) {
     if (is_signaled) {
         return;
         return;
     }
     }
 
 
     is_signaled = true;
     is_signaled = true;
-    SynchronizationObject::Signal();
+    NotifyAvailable();
+}
+
+bool ReadableEvent::IsSignaled() const {
+    ASSERT(kernel.GlobalSchedulerContext().IsLocked());
+
+    return is_signaled;
 }
 }
 
 
 void ReadableEvent::Clear() {
 void ReadableEvent::Clear() {

+ 6 - 6
src/core/hle/kernel/readable_event.h

@@ -4,8 +4,8 @@
 
 
 #pragma once
 #pragma once
 
 
+#include "core/hle/kernel/k_synchronization_object.h"
 #include "core/hle/kernel/object.h"
 #include "core/hle/kernel/object.h"
-#include "core/hle/kernel/synchronization_object.h"
 
 
 union ResultCode;
 union ResultCode;
 
 
@@ -14,7 +14,7 @@ namespace Kernel {
 class KernelCore;
 class KernelCore;
 class WritableEvent;
 class WritableEvent;
 
 
-class ReadableEvent final : public SynchronizationObject {
+class ReadableEvent final : public KSynchronizationObject {
     friend class WritableEvent;
     friend class WritableEvent;
 
 
 public:
 public:
@@ -32,9 +32,6 @@ public:
         return HANDLE_TYPE;
         return HANDLE_TYPE;
     }
     }
 
 
-    bool ShouldWait(const Thread* thread) const override;
-    void Acquire(Thread* thread) override;
-
     /// Unconditionally clears the readable event's state.
     /// Unconditionally clears the readable event's state.
     void Clear();
     void Clear();
 
 
@@ -46,11 +43,14 @@ public:
     ///      then ERR_INVALID_STATE will be returned.
     ///      then ERR_INVALID_STATE will be returned.
     ResultCode Reset();
     ResultCode Reset();
 
 
-    void Signal() override;
+    void Signal();
+
+    bool IsSignaled() const override;
 
 
 private:
 private:
     explicit ReadableEvent(KernelCore& kernel);
     explicit ReadableEvent(KernelCore& kernel);
 
 
+    bool is_signaled{};
     std::string name; ///< Name of event (optional)
     std::string name; ///< Name of event (optional)
 };
 };
 
 

+ 4 - 10
src/core/hle/kernel/server_port.cpp

@@ -13,7 +13,7 @@
 
 
 namespace Kernel {
 namespace Kernel {
 
 
-ServerPort::ServerPort(KernelCore& kernel) : SynchronizationObject{kernel} {}
+ServerPort::ServerPort(KernelCore& kernel) : KSynchronizationObject{kernel} {}
 ServerPort::~ServerPort() = default;
 ServerPort::~ServerPort() = default;
 
 
 ResultVal<std::shared_ptr<ServerSession>> ServerPort::Accept() {
 ResultVal<std::shared_ptr<ServerSession>> ServerPort::Accept() {
@@ -28,15 +28,9 @@ ResultVal<std::shared_ptr<ServerSession>> ServerPort::Accept() {
 
 
 void ServerPort::AppendPendingSession(std::shared_ptr<ServerSession> pending_session) {
 void ServerPort::AppendPendingSession(std::shared_ptr<ServerSession> pending_session) {
     pending_sessions.push_back(std::move(pending_session));
     pending_sessions.push_back(std::move(pending_session));
-}
-
-bool ServerPort::ShouldWait(const Thread* thread) const {
-    // If there are no pending sessions, we wait until a new one is added.
-    return pending_sessions.empty();
-}
-
-void ServerPort::Acquire(Thread* thread) {
-    ASSERT_MSG(!ShouldWait(thread), "object unavailable!");
+    if (pending_sessions.size() == 1) {
+        NotifyAvailable();
+    }
 }
 }
 
 
 bool ServerPort::IsSignaled() const {
 bool ServerPort::IsSignaled() const {

+ 2 - 5
src/core/hle/kernel/server_port.h

@@ -9,8 +9,8 @@
 #include <utility>
 #include <utility>
 #include <vector>
 #include <vector>
 #include "common/common_types.h"
 #include "common/common_types.h"
+#include "core/hle/kernel/k_synchronization_object.h"
 #include "core/hle/kernel/object.h"
 #include "core/hle/kernel/object.h"
-#include "core/hle/kernel/synchronization_object.h"
 #include "core/hle/result.h"
 #include "core/hle/result.h"
 
 
 namespace Kernel {
 namespace Kernel {
@@ -20,7 +20,7 @@ class KernelCore;
 class ServerSession;
 class ServerSession;
 class SessionRequestHandler;
 class SessionRequestHandler;
 
 
-class ServerPort final : public SynchronizationObject {
+class ServerPort final : public KSynchronizationObject {
 public:
 public:
     explicit ServerPort(KernelCore& kernel);
     explicit ServerPort(KernelCore& kernel);
     ~ServerPort() override;
     ~ServerPort() override;
@@ -79,9 +79,6 @@ public:
     /// waiting to be accepted by this port.
     /// waiting to be accepted by this port.
     void AppendPendingSession(std::shared_ptr<ServerSession> pending_session);
     void AppendPendingSession(std::shared_ptr<ServerSession> pending_session);
 
 
-    bool ShouldWait(const Thread* thread) const override;
-    void Acquire(Thread* thread) override;
-
     bool IsSignaled() const override;
     bool IsSignaled() const override;
 
 
 private:
 private:

+ 2 - 21
src/core/hle/kernel/server_session.cpp

@@ -24,7 +24,7 @@
 
 
 namespace Kernel {
 namespace Kernel {
 
 
-ServerSession::ServerSession(KernelCore& kernel) : SynchronizationObject{kernel} {}
+ServerSession::ServerSession(KernelCore& kernel) : KSynchronizationObject{kernel} {}
 
 
 ServerSession::~ServerSession() {
 ServerSession::~ServerSession() {
     kernel.ReleaseServiceThread(service_thread);
     kernel.ReleaseServiceThread(service_thread);
@@ -42,16 +42,6 @@ ResultVal<std::shared_ptr<ServerSession>> ServerSession::Create(KernelCore& kern
     return MakeResult(std::move(session));
     return MakeResult(std::move(session));
 }
 }
 
 
-bool ServerSession::ShouldWait(const Thread* thread) const {
-    // Closed sessions should never wait, an error will be returned from svcReplyAndReceive.
-    if (!parent->Client()) {
-        return false;
-    }
-
-    // Wait if we have no pending requests, or if we're currently handling a request.
-    return pending_requesting_threads.empty() || currently_handling != nullptr;
-}
-
 bool ServerSession::IsSignaled() const {
 bool ServerSession::IsSignaled() const {
     // Closed sessions should never wait, an error will be returned from svcReplyAndReceive.
     // Closed sessions should never wait, an error will be returned from svcReplyAndReceive.
     if (!parent->Client()) {
     if (!parent->Client()) {
@@ -62,15 +52,6 @@ bool ServerSession::IsSignaled() const {
     return !pending_requesting_threads.empty() && currently_handling == nullptr;
     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.
-    // TODO(Subv): What happens if the client endpoint is closed before any requests are made?
-    ASSERT(!pending_requesting_threads.empty());
-    currently_handling = pending_requesting_threads.back();
-    pending_requesting_threads.pop_back();
-}
-
 void ServerSession::ClientDisconnected() {
 void ServerSession::ClientDisconnected() {
     // We keep a shared pointer to the hle handler to keep it alive throughout
     // We keep a shared pointer to the hle handler to keep it alive throughout
     // the call to ClientDisconnected, as ClientDisconnected invalidates the
     // the call to ClientDisconnected, as ClientDisconnected invalidates the
@@ -172,7 +153,7 @@ ResultCode ServerSession::CompleteSyncRequest(HLERequestContext& context) {
     {
     {
         KScopedSchedulerLock lock(kernel);
         KScopedSchedulerLock lock(kernel);
         if (!context.IsThreadWaiting()) {
         if (!context.IsThreadWaiting()) {
-            context.GetThread().ResumeFromWait();
+            context.GetThread().Wakeup();
             context.GetThread().SetSynchronizationResults(nullptr, result);
             context.GetThread().SetSynchronizationResults(nullptr, result);
         }
         }
     }
     }

+ 4 - 8
src/core/hle/kernel/server_session.h

@@ -10,8 +10,8 @@
 #include <vector>
 #include <vector>
 
 
 #include "common/threadsafe_queue.h"
 #include "common/threadsafe_queue.h"
+#include "core/hle/kernel/k_synchronization_object.h"
 #include "core/hle/kernel/service_thread.h"
 #include "core/hle/kernel/service_thread.h"
-#include "core/hle/kernel/synchronization_object.h"
 #include "core/hle/result.h"
 #include "core/hle/result.h"
 
 
 namespace Core::Memory {
 namespace Core::Memory {
@@ -43,7 +43,7 @@ class Thread;
  * After the server replies to the request, the response is marshalled back to the caller's
  * After the server replies to the request, the response is marshalled back to the caller's
  * TLS buffer and control is transferred back to it.
  * TLS buffer and control is transferred back to it.
  */
  */
-class ServerSession final : public SynchronizationObject {
+class ServerSession final : public KSynchronizationObject {
     friend class ServiceThread;
     friend class ServiceThread;
 
 
 public:
 public:
@@ -77,8 +77,6 @@ public:
         return parent.get();
         return parent.get();
     }
     }
 
 
-    bool IsSignaled() const override;
-
     /**
     /**
      * Sets the HLE handler for the session. This handler will be called to service IPC requests
      * 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
      * instead of the regular IPC machinery. (The regular IPC machinery is currently not
@@ -100,10 +98,6 @@ public:
     ResultCode HandleSyncRequest(std::shared_ptr<Thread> thread, Core::Memory::Memory& memory,
     ResultCode HandleSyncRequest(std::shared_ptr<Thread> thread, Core::Memory::Memory& memory,
                                  Core::Timing::CoreTiming& core_timing);
                                  Core::Timing::CoreTiming& core_timing);
 
 
-    bool ShouldWait(const Thread* thread) const override;
-
-    void Acquire(Thread* thread) override;
-
     /// Called when a client disconnection occurs.
     /// Called when a client disconnection occurs.
     void ClientDisconnected();
     void ClientDisconnected();
 
 
@@ -130,6 +124,8 @@ public:
         convert_to_domain = true;
         convert_to_domain = true;
     }
     }
 
 
+    bool IsSignaled() const override;
+
 private:
 private:
     /// Queues a sync request from the emulated application.
     /// Queues a sync request from the emulated application.
     ResultCode QueueSyncRequest(std::shared_ptr<Thread> thread, Core::Memory::Memory& memory);
     ResultCode QueueSyncRequest(std::shared_ptr<Thread> thread, Core::Memory::Memory& memory);

+ 1 - 10
src/core/hle/kernel/session.cpp

@@ -9,7 +9,7 @@
 
 
 namespace Kernel {
 namespace Kernel {
 
 
-Session::Session(KernelCore& kernel) : SynchronizationObject{kernel} {}
+Session::Session(KernelCore& kernel) : KSynchronizationObject{kernel} {}
 Session::~Session() = default;
 Session::~Session() = default;
 
 
 Session::SessionPair Session::Create(KernelCore& kernel, std::string name) {
 Session::SessionPair Session::Create(KernelCore& kernel, std::string name) {
@@ -24,18 +24,9 @@ Session::SessionPair Session::Create(KernelCore& kernel, std::string name) {
     return std::make_pair(std::move(client_session), std::move(server_session));
     return std::make_pair(std::move(client_session), std::move(server_session));
 }
 }
 
 
-bool Session::ShouldWait(const Thread* thread) const {
-    UNIMPLEMENTED();
-    return {};
-}
-
 bool Session::IsSignaled() const {
 bool Session::IsSignaled() const {
     UNIMPLEMENTED();
     UNIMPLEMENTED();
     return true;
     return true;
 }
 }
 
 
-void Session::Acquire(Thread* thread) {
-    UNIMPLEMENTED();
-}
-
 } // namespace Kernel
 } // namespace Kernel

+ 2 - 6
src/core/hle/kernel/session.h

@@ -8,7 +8,7 @@
 #include <string>
 #include <string>
 #include <utility>
 #include <utility>
 
 
-#include "core/hle/kernel/synchronization_object.h"
+#include "core/hle/kernel/k_synchronization_object.h"
 
 
 namespace Kernel {
 namespace Kernel {
 
 
@@ -19,7 +19,7 @@ class ServerSession;
  * Parent structure to link the client and server endpoints of a session with their associated
  * Parent structure to link the client and server endpoints of a session with their associated
  * client port.
  * client port.
  */
  */
-class Session final : public SynchronizationObject {
+class Session final : public KSynchronizationObject {
 public:
 public:
     explicit Session(KernelCore& kernel);
     explicit Session(KernelCore& kernel);
     ~Session() override;
     ~Session() override;
@@ -37,12 +37,8 @@ public:
         return HANDLE_TYPE;
         return HANDLE_TYPE;
     }
     }
 
 
-    bool ShouldWait(const Thread* thread) const override;
-
     bool IsSignaled() const override;
     bool IsSignaled() const override;
 
 
-    void Acquire(Thread* thread) override;
-
     std::shared_ptr<ClientSession> Client() {
     std::shared_ptr<ClientSession> Client() {
         if (auto result{client.lock()}) {
         if (auto result{client.lock()}) {
             return result;
             return result;

+ 17 - 30
src/core/hle/kernel/svc.cpp

@@ -26,6 +26,7 @@
 #include "core/hle/kernel/handle_table.h"
 #include "core/hle/kernel/handle_table.h"
 #include "core/hle/kernel/k_scheduler.h"
 #include "core/hle/kernel/k_scheduler.h"
 #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
 #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
+#include "core/hle/kernel/k_synchronization_object.h"
 #include "core/hle/kernel/kernel.h"
 #include "core/hle/kernel/kernel.h"
 #include "core/hle/kernel/memory/memory_block.h"
 #include "core/hle/kernel/memory/memory_block.h"
 #include "core/hle/kernel/memory/page_table.h"
 #include "core/hle/kernel/memory/page_table.h"
@@ -38,7 +39,6 @@
 #include "core/hle/kernel/svc.h"
 #include "core/hle/kernel/svc.h"
 #include "core/hle/kernel/svc_types.h"
 #include "core/hle/kernel/svc_types.h"
 #include "core/hle/kernel/svc_wrap.h"
 #include "core/hle/kernel/svc_wrap.h"
-#include "core/hle/kernel/synchronization.h"
 #include "core/hle/kernel/thread.h"
 #include "core/hle/kernel/thread.h"
 #include "core/hle/kernel/time_manager.h"
 #include "core/hle/kernel/time_manager.h"
 #include "core/hle/kernel/transfer_memory.h"
 #include "core/hle/kernel/transfer_memory.h"
@@ -343,25 +343,14 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
     auto thread = kernel.CurrentScheduler()->GetCurrentThread();
     auto thread = kernel.CurrentScheduler()->GetCurrentThread();
     {
     {
         KScopedSchedulerLock lock(kernel);
         KScopedSchedulerLock lock(kernel);
-        thread->InvalidateHLECallback();
-        thread->SetStatus(ThreadStatus::WaitIPC);
+        thread->SetState(ThreadStatus::WaitIPC);
         session->SendSyncRequest(SharedFrom(thread), system.Memory(), system.CoreTiming());
         session->SendSyncRequest(SharedFrom(thread), system.Memory(), system.CoreTiming());
     }
     }
 
 
-    if (thread->HasHLECallback()) {
-        Handle event_handle = thread->GetHLETimeEvent();
-        if (event_handle != InvalidHandle) {
-            auto& time_manager = kernel.TimeManager();
-            time_manager.UnscheduleTimeEvent(event_handle);
-        }
-
-        {
-            KScopedSchedulerLock lock(kernel);
-            auto* sync_object = thread->GetHLESyncObject();
-            sync_object->RemoveWaitingThread(SharedFrom(thread));
-        }
-
-        thread->InvokeHLECallback(SharedFrom(thread));
+    Handle event_handle = thread->GetHLETimeEvent();
+    if (event_handle != InvalidHandle) {
+        auto& time_manager = kernel.TimeManager();
+        time_manager.UnscheduleTimeEvent(event_handle);
     }
     }
 
 
     return thread->GetSignalingResult();
     return thread->GetSignalingResult();
@@ -436,7 +425,7 @@ static ResultCode GetProcessId32(Core::System& system, u32* process_id_low, u32*
 }
 }
 
 
 /// Wait for the given handles to synchronize, timeout after the specified nanoseconds
 /// Wait for the given handles to synchronize, timeout after the specified nanoseconds
-static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr handles_address,
+static ResultCode WaitSynchronization(Core::System& system, s32* index, VAddr handles_address,
                                       u64 handle_count, s64 nano_seconds) {
                                       u64 handle_count, s64 nano_seconds) {
     LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, handle_count={}, nano_seconds={}",
     LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, handle_count={}, nano_seconds={}",
               handles_address, handle_count, nano_seconds);
               handles_address, handle_count, nano_seconds);
@@ -458,28 +447,26 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr
     }
     }
 
 
     auto& kernel = system.Kernel();
     auto& kernel = system.Kernel();
-    Thread::ThreadSynchronizationObjects objects(handle_count);
+    std::vector<KSynchronizationObject*> objects(handle_count);
     const auto& handle_table = kernel.CurrentProcess()->GetHandleTable();
     const auto& handle_table = kernel.CurrentProcess()->GetHandleTable();
 
 
     for (u64 i = 0; i < handle_count; ++i) {
     for (u64 i = 0; i < handle_count; ++i) {
         const Handle handle = memory.Read32(handles_address + i * sizeof(Handle));
         const Handle handle = memory.Read32(handles_address + i * sizeof(Handle));
-        const auto object = handle_table.Get<SynchronizationObject>(handle);
+        const auto object = handle_table.Get<KSynchronizationObject>(handle);
 
 
         if (object == nullptr) {
         if (object == nullptr) {
             LOG_ERROR(Kernel_SVC, "Object is a nullptr");
             LOG_ERROR(Kernel_SVC, "Object is a nullptr");
             return ERR_INVALID_HANDLE;
             return ERR_INVALID_HANDLE;
         }
         }
 
 
-        objects[i] = object;
+        objects[i] = object.get();
     }
     }
-    auto& synchronization = kernel.Synchronization();
-    const auto [result, handle_result] = synchronization.WaitFor(objects, nano_seconds);
-    *index = handle_result;
-    return result;
+    return KSynchronizationObject::Wait(kernel, index, objects.data(),
+                                        static_cast<s32>(objects.size()), nano_seconds);
 }
 }
 
 
 static ResultCode WaitSynchronization32(Core::System& system, u32 timeout_low, u32 handles_address,
 static ResultCode WaitSynchronization32(Core::System& system, u32 timeout_low, u32 handles_address,
-                                        s32 handle_count, u32 timeout_high, Handle* index) {
+                                        s32 handle_count, u32 timeout_high, s32* index) {
     const s64 nano_seconds{(static_cast<s64>(timeout_high) << 32) | static_cast<s64>(timeout_low)};
     const s64 nano_seconds{(static_cast<s64>(timeout_high) << 32) | static_cast<s64>(timeout_low)};
     return WaitSynchronization(system, index, handles_address, handle_count, nano_seconds);
     return WaitSynchronization(system, index, handles_address, handle_count, nano_seconds);
 }
 }
@@ -1655,7 +1642,7 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_add
 
 
         current_thread->SetSynchronizationResults(nullptr, RESULT_TIMEOUT);
         current_thread->SetSynchronizationResults(nullptr, RESULT_TIMEOUT);
 
 
-        if (thread->IsPendingTermination()) {
+        if (thread->IsTerminationRequested()) {
             lock.CancelSleep();
             lock.CancelSleep();
             return ERR_THREAD_TERMINATING;
             return ERR_THREAD_TERMINATING;
         }
         }
@@ -1674,7 +1661,7 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_add
         current_thread->SetCondVarWaitAddress(condition_variable_addr);
         current_thread->SetCondVarWaitAddress(condition_variable_addr);
         current_thread->SetMutexWaitAddress(mutex_addr);
         current_thread->SetMutexWaitAddress(mutex_addr);
         current_thread->SetWaitHandle(thread_handle);
         current_thread->SetWaitHandle(thread_handle);
-        current_thread->SetStatus(ThreadStatus::WaitCondVar);
+        current_thread->SetState(ThreadStatus::WaitCondVar);
         current_process->InsertConditionVariableThread(SharedFrom(current_thread));
         current_process->InsertConditionVariableThread(SharedFrom(current_thread));
     }
     }
 
 
@@ -1761,7 +1748,7 @@ static void SignalProcessWideKey(Core::System& system, VAddr condition_variable_
 
 
             thread->SetLockOwner(nullptr);
             thread->SetLockOwner(nullptr);
             thread->SetSynchronizationResults(nullptr, RESULT_SUCCESS);
             thread->SetSynchronizationResults(nullptr, RESULT_SUCCESS);
-            thread->ResumeFromWait();
+            thread->Wakeup();
         } else {
         } else {
             // The mutex is already owned by some other thread, make this thread wait on it.
             // The mutex is already owned by some other thread, make this thread wait on it.
             const Handle owner_handle = static_cast<Handle>(mutex_val & Mutex::MutexOwnerMask);
             const Handle owner_handle = static_cast<Handle>(mutex_val & Mutex::MutexOwnerMask);
@@ -1769,7 +1756,7 @@ static void SignalProcessWideKey(Core::System& system, VAddr condition_variable_
             auto owner = handle_table.Get<Thread>(owner_handle);
             auto owner = handle_table.Get<Thread>(owner_handle);
             ASSERT(owner);
             ASSERT(owner);
             if (thread->GetStatus() == ThreadStatus::WaitCondVar) {
             if (thread->GetStatus() == ThreadStatus::WaitCondVar) {
-                thread->SetStatus(ThreadStatus::WaitMutex);
+                thread->SetState(ThreadStatus::WaitMutex);
             }
             }
 
 
             owner->AddMutexWaiter(thread);
             owner->AddMutexWaiter(thread);

+ 5 - 4
src/core/hle/kernel/svc_wrap.h

@@ -215,9 +215,10 @@ void SvcWrap64(Core::System& system) {
         func(system, static_cast<u32>(Param(system, 0)), Param(system, 1), Param(system, 2)).raw);
         func(system, static_cast<u32>(Param(system, 0)), Param(system, 1), Param(system, 2)).raw);
 }
 }
 
 
-template <ResultCode func(Core::System&, u32*, u64, u64, s64)>
+// Used by WaitSynchronization
+template <ResultCode func(Core::System&, s32*, u64, u64, s64)>
 void SvcWrap64(Core::System& system) {
 void SvcWrap64(Core::System& system) {
-    u32 param_1 = 0;
+    s32 param_1 = 0;
     const u32 retval = func(system, &param_1, Param(system, 1), static_cast<u32>(Param(system, 2)),
     const u32 retval = func(system, &param_1, Param(system, 1), static_cast<u32>(Param(system, 2)),
                             static_cast<s64>(Param(system, 3)))
                             static_cast<s64>(Param(system, 3)))
                            .raw;
                            .raw;
@@ -539,9 +540,9 @@ void SvcWrap32(Core::System& system) {
 }
 }
 
 
 // Used by WaitSynchronization32
 // Used by WaitSynchronization32
-template <ResultCode func(Core::System&, u32, u32, s32, u32, Handle*)>
+template <ResultCode func(Core::System&, u32, u32, s32, u32, s32*)>
 void SvcWrap32(Core::System& system) {
 void SvcWrap32(Core::System& system) {
-    u32 param_1 = 0;
+    s32 param_1 = 0;
     const u32 retval = func(system, Param32(system, 0), Param32(system, 1), Param32(system, 2),
     const u32 retval = func(system, Param32(system, 0), Param32(system, 1), Param32(system, 2),
                             Param32(system, 3), &param_1)
                             Param32(system, 3), &param_1)
                            .raw;
                            .raw;

+ 0 - 116
src/core/hle/kernel/synchronization.cpp

@@ -1,116 +0,0 @@
-// 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/handle_table.h"
-#include "core/hle/kernel/k_scheduler.h"
-#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
-#include "core/hle/kernel/kernel.h"
-#include "core/hle/kernel/synchronization.h"
-#include "core/hle/kernel/synchronization_object.h"
-#include "core/hle/kernel/thread.h"
-#include "core/hle/kernel/time_manager.h"
-
-namespace Kernel {
-
-Synchronization::Synchronization(Core::System& system) : system{system} {}
-
-void Synchronization::SignalObject(SynchronizationObject& obj) const {
-    auto& kernel = system.Kernel();
-    KScopedSchedulerLock lock(kernel);
-    if (obj.IsSignaled()) {
-        for (auto thread : obj.GetWaitingThreads()) {
-            if (thread->GetSchedulingStatus() == ThreadSchedStatus::Paused) {
-                if (thread->GetStatus() != ThreadStatus::WaitHLEEvent) {
-                    ASSERT(thread->GetStatus() == ThreadStatus::WaitSynch);
-                    ASSERT(thread->IsWaitingSync());
-                }
-                thread->SetSynchronizationResults(&obj, RESULT_SUCCESS);
-                thread->ResumeFromWait();
-            }
-        }
-        obj.ClearWaitingThreads();
-    }
-}
-
-std::pair<ResultCode, Handle> Synchronization::WaitFor(
-    std::vector<std::shared_ptr<SynchronizationObject>>& sync_objects, s64 nano_seconds) {
-    auto& kernel = system.Kernel();
-    auto* const thread = kernel.CurrentScheduler()->GetCurrentThread();
-    Handle event_handle = InvalidHandle;
-    {
-        KScopedSchedulerLockAndSleep lock(kernel, event_handle, thread, nano_seconds);
-        const 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);
-            const u32 index = static_cast<s32>(std::distance(sync_objects.begin(), itr));
-            lock.CancelSleep();
-            return {RESULT_SUCCESS, index};
-        }
-
-        if (nano_seconds == 0) {
-            lock.CancelSleep();
-            return {RESULT_TIMEOUT, InvalidHandle};
-        }
-
-        if (thread->IsPendingTermination()) {
-            lock.CancelSleep();
-            return {ERR_THREAD_TERMINATING, InvalidHandle};
-        }
-
-        if (thread->IsSyncCancelled()) {
-            thread->SetSyncCancelled(false);
-            lock.CancelSleep();
-            return {ERR_SYNCHRONIZATION_CANCELED, InvalidHandle};
-        }
-
-        for (auto& object : sync_objects) {
-            object->AddWaitingThread(SharedFrom(thread));
-        }
-
-        thread->SetSynchronizationObjects(&sync_objects);
-        thread->SetSynchronizationResults(nullptr, RESULT_TIMEOUT);
-        thread->SetStatus(ThreadStatus::WaitSynch);
-        thread->SetWaitingSync(true);
-    }
-    thread->SetWaitingSync(false);
-
-    if (event_handle != InvalidHandle) {
-        auto& time_manager = kernel.TimeManager();
-        time_manager.UnscheduleTimeEvent(event_handle);
-    }
-
-    {
-        KScopedSchedulerLock lock(kernel);
-        ResultCode signaling_result = thread->GetSignalingResult();
-        SynchronizationObject* signaling_object = thread->GetSignalingObject();
-        thread->SetSynchronizationObjects(nullptr);
-        auto shared_thread = SharedFrom(thread);
-        for (auto& obj : sync_objects) {
-            obj->RemoveWaitingThread(shared_thread);
-        }
-        if (signaling_object != nullptr) {
-            const auto itr = std::find_if(
-                sync_objects.begin(), sync_objects.end(),
-                [signaling_object](const std::shared_ptr<SynchronizationObject>& object) {
-                    return object.get() == signaling_object;
-                });
-            ASSERT(itr != sync_objects.end());
-            signaling_object->Acquire(thread);
-            const u32 index = static_cast<s32>(std::distance(sync_objects.begin(), itr));
-            return {signaling_result, index};
-        }
-        return {signaling_result, -1};
-    }
-}
-
-} // namespace Kernel

+ 0 - 44
src/core/hle/kernel/synchronization.h

@@ -1,44 +0,0 @@
-// 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 <vector>
-
-#include "core/hle/kernel/object.h"
-#include "core/hle/result.h"
-
-namespace Core {
-class System;
-} // namespace Core
-
-namespace Kernel {
-
-class SynchronizationObject;
-
-/**
- * The 'Synchronization' class is an interface for handling synchronization methods
- * used by Synchronization objects and synchronization SVCs. This centralizes processing of
- * such
- */
-class Synchronization {
-public:
-    explicit Synchronization(Core::System& system);
-
-    /// Signals a synchronization object, waking up all its waiting threads
-    void SignalObject(SynchronizationObject& obj) const;
-
-    /// Tries to see if waiting for any of the sync_objects is necessary, if not
-    /// it returns Success and the handle index of the signaled sync object. In
-    /// case not, the current thread will be locked and wait for nano_seconds or
-    /// for a synchronization object to signal.
-    std::pair<ResultCode, Handle> WaitFor(
-        std::vector<std::shared_ptr<SynchronizationObject>>& sync_objects, s64 nano_seconds);
-
-private:
-    Core::System& system;
-};
-} // namespace Kernel

+ 0 - 49
src/core/hle/kernel/synchronization_object.cpp

@@ -1,49 +0,0 @@
-// Copyright 2014 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include <algorithm>
-#include "common/assert.h"
-#include "common/common_types.h"
-#include "common/logging/log.h"
-#include "core/core.h"
-#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"
-
-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())
-        waiting_threads.push_back(std::move(thread));
-}
-
-void SynchronizationObject::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
-    // waiting threads list multiple times.
-    if (itr != waiting_threads.end())
-        waiting_threads.erase(itr);
-}
-
-void SynchronizationObject::ClearWaitingThreads() {
-    waiting_threads.clear();
-}
-
-const std::vector<std::shared_ptr<Thread>>& SynchronizationObject::GetWaitingThreads() const {
-    return waiting_threads;
-}
-
-} // namespace Kernel

+ 0 - 77
src/core/hle/kernel/synchronization_object.h

@@ -1,77 +0,0 @@
-// Copyright 2014 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#pragma once
-
-#include <atomic>
-#include <memory>
-#include <vector>
-
-#include "core/hle/kernel/object.h"
-
-namespace Kernel {
-
-class KernelCore;
-class Synchronization;
-class Thread;
-
-/// Class that represents a Kernel object that a thread can be waiting on
-class SynchronizationObject : public Object {
-public:
-    explicit SynchronizationObject(KernelCore& kernel);
-    ~SynchronizationObject() override;
-
-    /**
-     * Check if the specified thread should wait until the object is available
-     * @param thread The thread about which we're deciding.
-     * @return True if the current thread should wait due to this object being unavailable
-     */
-    virtual bool ShouldWait(const Thread* thread) const = 0;
-
-    /// 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
-     */
-    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(std::shared_ptr<Thread> thread);
-
-    /// Get a const reference to the waiting threads list for debug use
-    const std::vector<std::shared_ptr<Thread>>& GetWaitingThreads() const;
-
-    void ClearWaitingThreads();
-
-protected:
-    std::atomic_bool is_signaled{}; // Tells if this sync object is signaled
-
-private:
-    /// Threads waiting for this object to become available
-    std::vector<std::shared_ptr<Thread>> waiting_threads;
-};
-
-// Specialization of DynamicObjectCast for SynchronizationObjects
-template <>
-inline std::shared_ptr<SynchronizationObject> DynamicObjectCast<SynchronizationObject>(
-    std::shared_ptr<Object> object) {
-    if (object != nullptr && object->IsWaitable()) {
-        return std::static_pointer_cast<SynchronizationObject>(object);
-    }
-    return nullptr;
-}
-
-} // namespace Kernel

+ 19 - 47
src/core/hle/kernel/thread.cpp

@@ -34,26 +34,19 @@
 
 
 namespace Kernel {
 namespace Kernel {
 
 
-bool Thread::ShouldWait(const Thread* thread) const {
-    return status != ThreadStatus::Dead;
-}
-
 bool Thread::IsSignaled() const {
 bool Thread::IsSignaled() const {
-    return status == ThreadStatus::Dead;
+    return signaled;
 }
 }
 
 
-void Thread::Acquire(Thread* thread) {
-    ASSERT_MSG(!ShouldWait(thread), "object unavailable!");
-}
-
-Thread::Thread(KernelCore& kernel) : SynchronizationObject{kernel} {}
+Thread::Thread(KernelCore& kernel) : KSynchronizationObject{kernel} {}
 Thread::~Thread() = default;
 Thread::~Thread() = default;
 
 
 void Thread::Stop() {
 void Thread::Stop() {
     {
     {
         KScopedSchedulerLock lock(kernel);
         KScopedSchedulerLock lock(kernel);
-        SetStatus(ThreadStatus::Dead);
-        Signal();
+        SetState(ThreadStatus::Dead);
+        signaled = true;
+        NotifyAvailable();
         kernel.GlobalHandleTable().Close(global_handle);
         kernel.GlobalHandleTable().Close(global_handle);
 
 
         if (owner_process) {
         if (owner_process) {
@@ -67,7 +60,7 @@ void Thread::Stop() {
     global_handle = 0;
     global_handle = 0;
 }
 }
 
 
-void Thread::ResumeFromWait() {
+void Thread::Wakeup() {
     KScopedSchedulerLock lock(kernel);
     KScopedSchedulerLock lock(kernel);
     switch (status) {
     switch (status) {
     case ThreadStatus::Paused:
     case ThreadStatus::Paused:
@@ -82,9 +75,6 @@ void Thread::ResumeFromWait() {
         break;
         break;
 
 
     case ThreadStatus::Ready:
     case ThreadStatus::Ready:
-        // The thread's wakeup callback must have already been cleared when the thread was first
-        // awoken.
-        ASSERT(hle_callback == nullptr);
         // If the thread is waiting on multiple wait objects, it might be awoken more than once
         // If the thread is waiting on multiple wait objects, it might be awoken more than once
         // before actually resuming. We can ignore subsequent wakeups if the thread status has
         // before actually resuming. We can ignore subsequent wakeups if the thread status has
         // already been set to ThreadStatus::Ready.
         // already been set to ThreadStatus::Ready.
@@ -96,30 +86,30 @@ void Thread::ResumeFromWait() {
         return;
         return;
     }
     }
 
 
-    SetStatus(ThreadStatus::Ready);
+    SetState(ThreadStatus::Ready);
 }
 }
 
 
 void Thread::OnWakeUp() {
 void Thread::OnWakeUp() {
     KScopedSchedulerLock lock(kernel);
     KScopedSchedulerLock lock(kernel);
-    SetStatus(ThreadStatus::Ready);
+    SetState(ThreadStatus::Ready);
 }
 }
 
 
 ResultCode Thread::Start() {
 ResultCode Thread::Start() {
     KScopedSchedulerLock lock(kernel);
     KScopedSchedulerLock lock(kernel);
-    SetStatus(ThreadStatus::Ready);
+    SetState(ThreadStatus::Ready);
     return RESULT_SUCCESS;
     return RESULT_SUCCESS;
 }
 }
 
 
 void Thread::CancelWait() {
 void Thread::CancelWait() {
     KScopedSchedulerLock lock(kernel);
     KScopedSchedulerLock lock(kernel);
-    if (GetSchedulingStatus() != ThreadSchedStatus::Paused || !is_waiting_on_sync) {
+    if (GetState() != ThreadSchedStatus::Paused || !is_cancellable) {
         is_sync_cancelled = true;
         is_sync_cancelled = true;
         return;
         return;
     }
     }
     // TODO(Blinkhawk): Implement cancel of server session
     // TODO(Blinkhawk): Implement cancel of server session
     is_sync_cancelled = false;
     is_sync_cancelled = false;
     SetSynchronizationResults(nullptr, ERR_SYNCHRONIZATION_CANCELED);
     SetSynchronizationResults(nullptr, ERR_SYNCHRONIZATION_CANCELED);
-    SetStatus(ThreadStatus::Ready);
+    SetState(ThreadStatus::Ready);
 }
 }
 
 
 static void ResetThreadContext32(Core::ARM_Interface::ThreadContext32& context, u32 stack_top,
 static void ResetThreadContext32(Core::ARM_Interface::ThreadContext32& context, u32 stack_top,
@@ -194,7 +184,6 @@ ResultVal<std::shared_ptr<Thread>> Thread::Create(Core::System& system, ThreadTy
     thread->processor_id = processor_id;
     thread->processor_id = processor_id;
     thread->ideal_core = processor_id;
     thread->ideal_core = processor_id;
     thread->affinity_mask.SetAffinity(processor_id, true);
     thread->affinity_mask.SetAffinity(processor_id, true);
-    thread->wait_objects = nullptr;
     thread->mutex_wait_address = 0;
     thread->mutex_wait_address = 0;
     thread->condvar_wait_address = 0;
     thread->condvar_wait_address = 0;
     thread->wait_handle = 0;
     thread->wait_handle = 0;
@@ -202,6 +191,7 @@ ResultVal<std::shared_ptr<Thread>> Thread::Create(Core::System& system, ThreadTy
     thread->global_handle = kernel.GlobalHandleTable().Create(thread).Unwrap();
     thread->global_handle = kernel.GlobalHandleTable().Create(thread).Unwrap();
     thread->owner_process = owner_process;
     thread->owner_process = owner_process;
     thread->type = type_flags;
     thread->type = type_flags;
+    thread->signaled = false;
     if ((type_flags & THREADTYPE_IDLE) == 0) {
     if ((type_flags & THREADTYPE_IDLE) == 0) {
         auto& scheduler = kernel.GlobalSchedulerContext();
         auto& scheduler = kernel.GlobalSchedulerContext();
         scheduler.AddThread(thread);
         scheduler.AddThread(thread);
@@ -234,24 +224,18 @@ void Thread::SetPriority(u32 priority) {
     UpdatePriority();
     UpdatePriority();
 }
 }
 
 
-void Thread::SetSynchronizationResults(SynchronizationObject* object, ResultCode result) {
+void Thread::SetSynchronizationResults(KSynchronizationObject* object, ResultCode result) {
     signaling_object = object;
     signaling_object = object;
     signaling_result = result;
     signaling_result = result;
 }
 }
 
 
-s32 Thread::GetSynchronizationObjectIndex(std::shared_ptr<SynchronizationObject> 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);
-}
-
 VAddr Thread::GetCommandBufferAddress() const {
 VAddr Thread::GetCommandBufferAddress() const {
     // Offset from the start of TLS at which the IPC command buffer begins.
     // Offset from the start of TLS at which the IPC command buffer begins.
     constexpr u64 command_header_offset = 0x80;
     constexpr u64 command_header_offset = 0x80;
     return GetTLSAddress() + command_header_offset;
     return GetTLSAddress() + command_header_offset;
 }
 }
 
 
-void Thread::SetStatus(ThreadStatus new_status) {
+void Thread::SetState(ThreadStatus new_status) {
     if (new_status == status) {
     if (new_status == status) {
         return;
         return;
     }
     }
@@ -351,28 +335,16 @@ void Thread::UpdatePriority() {
     lock_owner->UpdatePriority();
     lock_owner->UpdatePriority();
 }
 }
 
 
-bool Thread::AllSynchronizationObjectsReady() const {
-    return std::none_of(wait_objects->begin(), wait_objects->end(),
-                        [this](const std::shared_ptr<SynchronizationObject>& object) {
-                            return object->ShouldWait(this);
-                        });
-}
-
-bool Thread::InvokeHLECallback(std::shared_ptr<Thread> thread) {
-    ASSERT(hle_callback);
-    return hle_callback(std::move(thread));
-}
-
 ResultCode Thread::SetActivity(ThreadActivity value) {
 ResultCode Thread::SetActivity(ThreadActivity value) {
     KScopedSchedulerLock lock(kernel);
     KScopedSchedulerLock lock(kernel);
 
 
-    auto sched_status = GetSchedulingStatus();
+    auto sched_status = GetState();
 
 
     if (sched_status != ThreadSchedStatus::Runnable && sched_status != ThreadSchedStatus::Paused) {
     if (sched_status != ThreadSchedStatus::Runnable && sched_status != ThreadSchedStatus::Paused) {
         return ERR_INVALID_STATE;
         return ERR_INVALID_STATE;
     }
     }
 
 
-    if (IsPendingTermination()) {
+    if (IsTerminationRequested()) {
         return RESULT_SUCCESS;
         return RESULT_SUCCESS;
     }
     }
 
 
@@ -394,7 +366,7 @@ ResultCode Thread::Sleep(s64 nanoseconds) {
     Handle event_handle{};
     Handle event_handle{};
     {
     {
         KScopedSchedulerLockAndSleep lock(kernel, event_handle, this, nanoseconds);
         KScopedSchedulerLockAndSleep lock(kernel, event_handle, this, nanoseconds);
-        SetStatus(ThreadStatus::WaitSleep);
+        SetState(ThreadStatus::WaitSleep);
     }
     }
 
 
     if (event_handle != InvalidHandle) {
     if (event_handle != InvalidHandle) {
@@ -407,7 +379,7 @@ ResultCode Thread::Sleep(s64 nanoseconds) {
 void Thread::AddSchedulingFlag(ThreadSchedFlags flag) {
 void Thread::AddSchedulingFlag(ThreadSchedFlags flag) {
     const u32 old_state = scheduling_state;
     const u32 old_state = scheduling_state;
     pausing_state |= static_cast<u32>(flag);
     pausing_state |= static_cast<u32>(flag);
-    const u32 base_scheduling = static_cast<u32>(GetSchedulingStatus());
+    const u32 base_scheduling = static_cast<u32>(GetState());
     scheduling_state = base_scheduling | pausing_state;
     scheduling_state = base_scheduling | pausing_state;
     KScheduler::OnThreadStateChanged(kernel, this, old_state);
     KScheduler::OnThreadStateChanged(kernel, this, old_state);
 }
 }
@@ -415,7 +387,7 @@ void Thread::AddSchedulingFlag(ThreadSchedFlags flag) {
 void Thread::RemoveSchedulingFlag(ThreadSchedFlags flag) {
 void Thread::RemoveSchedulingFlag(ThreadSchedFlags flag) {
     const u32 old_state = scheduling_state;
     const u32 old_state = scheduling_state;
     pausing_state &= ~static_cast<u32>(flag);
     pausing_state &= ~static_cast<u32>(flag);
-    const u32 base_scheduling = static_cast<u32>(GetSchedulingStatus());
+    const u32 base_scheduling = static_cast<u32>(GetState());
     scheduling_state = base_scheduling | pausing_state;
     scheduling_state = base_scheduling | pausing_state;
     KScheduler::OnThreadStateChanged(kernel, this, old_state);
     KScheduler::OnThreadStateChanged(kernel, this, old_state);
 }
 }

+ 46 - 85
src/core/hle/kernel/thread.h

@@ -14,8 +14,8 @@
 #include "common/spin_lock.h"
 #include "common/spin_lock.h"
 #include "core/arm/arm_interface.h"
 #include "core/arm/arm_interface.h"
 #include "core/hle/kernel/k_affinity_mask.h"
 #include "core/hle/kernel/k_affinity_mask.h"
+#include "core/hle/kernel/k_synchronization_object.h"
 #include "core/hle/kernel/object.h"
 #include "core/hle/kernel/object.h"
-#include "core/hle/kernel/synchronization_object.h"
 #include "core/hle/result.h"
 #include "core/hle/result.h"
 
 
 namespace Common {
 namespace Common {
@@ -117,7 +117,7 @@ enum class ThreadSchedMasks : u32 {
     ForcePauseMask = 0x0070,
     ForcePauseMask = 0x0070,
 };
 };
 
 
-class Thread final : public SynchronizationObject {
+class Thread final : public KSynchronizationObject {
 public:
 public:
     explicit Thread(KernelCore& kernel);
     explicit Thread(KernelCore& kernel);
     ~Thread() override;
     ~Thread() override;
@@ -127,10 +127,6 @@ public:
     using ThreadContext32 = Core::ARM_Interface::ThreadContext32;
     using ThreadContext32 = Core::ARM_Interface::ThreadContext32;
     using ThreadContext64 = Core::ARM_Interface::ThreadContext64;
     using ThreadContext64 = Core::ARM_Interface::ThreadContext64;
 
 
-    using ThreadSynchronizationObjects = std::vector<std::shared_ptr<SynchronizationObject>>;
-
-    using HLECallback = std::function<bool(std::shared_ptr<Thread> thread)>;
-
     /**
     /**
      * Creates and returns a new thread. The new thread is immediately scheduled
      * Creates and returns a new thread. The new thread is immediately scheduled
      * @param system The instance of the whole system
      * @param system The instance of the whole system
@@ -186,10 +182,6 @@ public:
         return HANDLE_TYPE;
         return HANDLE_TYPE;
     }
     }
 
 
-    bool ShouldWait(const Thread* thread) const override;
-    void Acquire(Thread* thread) override;
-    bool IsSignaled() const override;
-
     /**
     /**
      * Gets the thread's current priority
      * Gets the thread's current priority
      * @return The current thread's priority
      * @return The current thread's priority
@@ -233,12 +225,14 @@ public:
     }
     }
 
 
     /// Resumes a thread from waiting
     /// Resumes a thread from waiting
-    void ResumeFromWait();
+    void Wakeup();
 
 
     void OnWakeUp();
     void OnWakeUp();
 
 
     ResultCode Start();
     ResultCode Start();
 
 
+    virtual bool IsSignaled() const override;
+
     /// Cancels a waiting operation that this thread may or may not be within.
     /// Cancels a waiting operation that this thread may or may not be within.
     ///
     ///
     /// When the thread is within a waiting state, this will set the thread's
     /// When the thread is within a waiting state, this will set the thread's
@@ -247,29 +241,20 @@ public:
     ///
     ///
     void CancelWait();
     void CancelWait();
 
 
-    void SetSynchronizationResults(SynchronizationObject* object, ResultCode result);
+    void SetSynchronizationResults(KSynchronizationObject* object, ResultCode result);
 
 
-    SynchronizationObject* GetSignalingObject() const {
-        return signaling_object;
+    void SetSyncedObject(KSynchronizationObject* object, ResultCode result) {
+        SetSynchronizationResults(object, result);
     }
     }
 
 
-    ResultCode GetSignalingResult() const {
+    ResultCode GetWaitResult(KSynchronizationObject** out) const {
+        *out = this->signaling_object;
         return signaling_result;
         return signaling_result;
     }
     }
 
 
-    /**
-     * Retrieves the index that this particular object occupies in the list of objects
-     * that the thread passed to WaitSynchronization, starting the search from the last element.
-     *
-     * It is used to set the output index of WaitSynchronization when the thread is awakened.
-     *
-     * When a thread wakes up due to an object signal, the kernel will use the index of the last
-     * matching object in the wait objects list in case of having multiple instances of the same
-     * object in the list.
-     *
-     * @param object Object to query the index of.
-     */
-    s32 GetSynchronizationObjectIndex(std::shared_ptr<SynchronizationObject> object) const;
+    ResultCode GetSignalingResult() const {
+        return signaling_result;
+    }
 
 
     /**
     /**
      * Stops a thread, invalidating it from further use
      * Stops a thread, invalidating it from further use
@@ -345,7 +330,7 @@ public:
         return status;
         return status;
     }
     }
 
 
-    void SetStatus(ThreadStatus new_status);
+    void SetState(ThreadStatus new_status);
 
 
     s64 GetLastScheduledTick() const {
     s64 GetLastScheduledTick() const {
         return this->last_scheduled_tick;
         return this->last_scheduled_tick;
@@ -387,24 +372,6 @@ public:
         return owner_process;
         return owner_process;
     }
     }
 
 
-    const ThreadSynchronizationObjects& GetSynchronizationObjects() const {
-        return *wait_objects;
-    }
-
-    void SetSynchronizationObjects(ThreadSynchronizationObjects* objects) {
-        wait_objects = objects;
-    }
-
-    void ClearSynchronizationObjects() {
-        for (const auto& waiting_object : *wait_objects) {
-            waiting_object->RemoveWaitingThread(SharedFrom(this));
-        }
-        wait_objects->clear();
-    }
-
-    /// Determines whether all the objects this thread is waiting on are ready.
-    bool AllSynchronizationObjectsReady() const;
-
     const MutexWaitingThreads& GetMutexWaitingThreads() const {
     const MutexWaitingThreads& GetMutexWaitingThreads() const {
         return wait_mutex_threads;
         return wait_mutex_threads;
     }
     }
@@ -449,34 +416,14 @@ public:
         arb_wait_address = address;
         arb_wait_address = address;
     }
     }
 
 
-    bool HasHLECallback() const {
-        return hle_callback != nullptr;
-    }
-
-    void SetHLECallback(HLECallback callback) {
-        hle_callback = std::move(callback);
-    }
-
     void SetHLETimeEvent(Handle time_event) {
     void SetHLETimeEvent(Handle time_event) {
         hle_time_event = time_event;
         hle_time_event = time_event;
     }
     }
 
 
-    void SetHLESyncObject(SynchronizationObject* object) {
-        hle_object = object;
-    }
-
     Handle GetHLETimeEvent() const {
     Handle GetHLETimeEvent() const {
         return hle_time_event;
         return hle_time_event;
     }
     }
 
 
-    SynchronizationObject* GetHLESyncObject() const {
-        return hle_object;
-    }
-
-    void InvalidateHLECallback() {
-        SetHLECallback(nullptr);
-    }
-
     bool InvokeHLECallback(std::shared_ptr<Thread> thread);
     bool InvokeHLECallback(std::shared_ptr<Thread> thread);
 
 
     u32 GetIdealCore() const {
     u32 GetIdealCore() const {
@@ -500,7 +447,7 @@ public:
         this->schedule_count = count;
         this->schedule_count = count;
     }
     }
 
 
-    ThreadSchedStatus GetSchedulingStatus() const {
+    ThreadSchedStatus GetState() const {
         return static_cast<ThreadSchedStatus>(scheduling_state &
         return static_cast<ThreadSchedStatus>(scheduling_state &
                                               static_cast<u32>(ThreadSchedMasks::LowMask));
                                               static_cast<u32>(ThreadSchedMasks::LowMask));
     }
     }
@@ -517,12 +464,12 @@ public:
         is_running = value;
         is_running = value;
     }
     }
 
 
-    bool IsSyncCancelled() const {
+    bool IsWaitCancelled() const {
         return is_sync_cancelled;
         return is_sync_cancelled;
     }
     }
 
 
-    void SetSyncCancelled(bool value) {
-        is_sync_cancelled = value;
+    void ClearWaitCancelled() {
+        is_sync_cancelled = false;
     }
     }
 
 
     Handle GetGlobalHandle() const {
     Handle GetGlobalHandle() const {
@@ -537,16 +484,20 @@ public:
         waiting_for_arbitration = set;
         waiting_for_arbitration = set;
     }
     }
 
 
-    bool IsWaitingSync() const {
-        return is_waiting_on_sync;
+    bool IsCancellable() const {
+        return is_cancellable;
     }
     }
 
 
-    void SetWaitingSync(bool is_waiting) {
-        is_waiting_on_sync = is_waiting;
+    void SetCancellable() {
+        is_cancellable = true;
     }
     }
 
 
-    bool IsPendingTermination() const {
-        return will_be_terminated || GetSchedulingStatus() == ThreadSchedStatus::Exited;
+    void ClearCancellable() {
+        is_cancellable = false;
+    }
+
+    bool IsTerminationRequested() const {
+        return will_be_terminated || GetState() == ThreadSchedStatus::Exited;
     }
     }
 
 
     bool IsPaused() const {
     bool IsPaused() const {
@@ -622,6 +573,18 @@ public:
         disable_count--;
         disable_count--;
     }
     }
 
 
+    void SetWaitObjectsForDebugging(KSynchronizationObject** objects, s32 num_objects) {
+        wait_objects_for_debugging.clear();
+        wait_objects_for_debugging.reserve(num_objects);
+        for (auto i = 0; i < num_objects; ++i) {
+            wait_objects_for_debugging.emplace_back(objects[i]);
+        }
+    }
+
+    const std::vector<KSynchronizationObject*>& GetWaitObjectsForDebugging() const {
+        return wait_objects_for_debugging;
+    }
+
 private:
 private:
     friend class GlobalSchedulerContext;
     friend class GlobalSchedulerContext;
     friend class KScheduler;
     friend class KScheduler;
@@ -630,7 +593,6 @@ private:
     void SetSchedulingStatus(ThreadSchedStatus new_status);
     void SetSchedulingStatus(ThreadSchedStatus new_status);
     void AddSchedulingFlag(ThreadSchedFlags flag);
     void AddSchedulingFlag(ThreadSchedFlags flag);
     void RemoveSchedulingFlag(ThreadSchedFlags flag);
     void RemoveSchedulingFlag(ThreadSchedFlags flag);
-
     void SetCurrentPriority(u32 new_priority);
     void SetCurrentPriority(u32 new_priority);
 
 
     Common::SpinLock context_guard{};
     Common::SpinLock context_guard{};
@@ -671,10 +633,10 @@ private:
     Process* owner_process;
     Process* owner_process;
 
 
     /// Objects that the thread is waiting on, in the same order as they were
     /// Objects that the thread is waiting on, in the same order as they were
-    /// passed to WaitSynchronization.
-    ThreadSynchronizationObjects* wait_objects;
+    /// passed to WaitSynchronization. This is used for debugging only.
+    std::vector<KSynchronizationObject*> wait_objects_for_debugging;
 
 
-    SynchronizationObject* signaling_object;
+    KSynchronizationObject* signaling_object;
     ResultCode signaling_result{RESULT_SUCCESS};
     ResultCode signaling_result{RESULT_SUCCESS};
 
 
     /// List of threads that are waiting for a mutex that is held by this thread.
     /// List of threads that are waiting for a mutex that is held by this thread.
@@ -697,10 +659,7 @@ private:
     /// Handle used as userdata to reference this object when inserting into the CoreTiming queue.
     /// Handle used as userdata to reference this object when inserting into the CoreTiming queue.
     Handle global_handle = 0;
     Handle global_handle = 0;
 
 
-    /// Callback for HLE Events
-    HLECallback hle_callback;
     Handle hle_time_event;
     Handle hle_time_event;
-    SynchronizationObject* hle_object;
 
 
     KScheduler* scheduler = nullptr;
     KScheduler* scheduler = nullptr;
 
 
@@ -714,7 +673,7 @@ private:
 
 
     u32 pausing_state = 0;
     u32 pausing_state = 0;
     bool is_running = false;
     bool is_running = false;
-    bool is_waiting_on_sync = false;
+    bool is_cancellable = false;
     bool is_sync_cancelled = false;
     bool is_sync_cancelled = false;
 
 
     bool is_continuous_on_svc = false;
     bool is_continuous_on_svc = false;
@@ -725,6 +684,8 @@ private:
 
 
     bool was_running = false;
     bool was_running = false;
 
 
+    bool signaled{};
+
     std::string name;
     std::string name;
 };
 };
 
 

+ 0 - 3
src/core/hle/service/sm/sm.cpp

@@ -139,9 +139,6 @@ void SM::GetService(Kernel::HLERequestContext& ctx) {
         server_port->AppendPendingSession(server);
         server_port->AppendPendingSession(server);
     }
     }
 
 
-    // Wake the threads waiting on the ServerPort
-    server_port->Signal();
-
     LOG_DEBUG(Service_SM, "called service={} -> session={}", name, client->GetObjectId());
     LOG_DEBUG(Service_SM, "called service={} -> session={}", name, client->GetObjectId());
     IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
     IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
     rb.Push(RESULT_SUCCESS);
     rb.Push(RESULT_SUCCESS);

+ 10 - 9
src/yuzu/debugger/wait_tree.cpp

@@ -14,10 +14,10 @@
 #include "core/core.h"
 #include "core/core.h"
 #include "core/hle/kernel/handle_table.h"
 #include "core/hle/kernel/handle_table.h"
 #include "core/hle/kernel/k_scheduler.h"
 #include "core/hle/kernel/k_scheduler.h"
+#include "core/hle/kernel/k_synchronization_object.h"
 #include "core/hle/kernel/mutex.h"
 #include "core/hle/kernel/mutex.h"
 #include "core/hle/kernel/process.h"
 #include "core/hle/kernel/process.h"
 #include "core/hle/kernel/readable_event.h"
 #include "core/hle/kernel/readable_event.h"
-#include "core/hle/kernel/synchronization_object.h"
 #include "core/hle/kernel/thread.h"
 #include "core/hle/kernel/thread.h"
 #include "core/memory.h"
 #include "core/memory.h"
 
 
@@ -169,7 +169,8 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeCallstack::GetChildren() cons
     return list;
     return list;
 }
 }
 
 
-WaitTreeSynchronizationObject::WaitTreeSynchronizationObject(const Kernel::SynchronizationObject& o)
+WaitTreeSynchronizationObject::WaitTreeSynchronizationObject(
+    const Kernel::KSynchronizationObject& o)
     : object(o) {}
     : object(o) {}
 WaitTreeSynchronizationObject::~WaitTreeSynchronizationObject() = default;
 WaitTreeSynchronizationObject::~WaitTreeSynchronizationObject() = default;
 
 
@@ -188,7 +189,7 @@ QString WaitTreeSynchronizationObject::GetText() const {
 }
 }
 
 
 std::unique_ptr<WaitTreeSynchronizationObject> WaitTreeSynchronizationObject::make(
 std::unique_ptr<WaitTreeSynchronizationObject> WaitTreeSynchronizationObject::make(
-    const Kernel::SynchronizationObject& object) {
+    const Kernel::KSynchronizationObject& object) {
     switch (object.GetHandleType()) {
     switch (object.GetHandleType()) {
     case Kernel::HandleType::ReadableEvent:
     case Kernel::HandleType::ReadableEvent:
         return std::make_unique<WaitTreeEvent>(static_cast<const Kernel::ReadableEvent&>(object));
         return std::make_unique<WaitTreeEvent>(static_cast<const Kernel::ReadableEvent&>(object));
@@ -202,7 +203,7 @@ std::unique_ptr<WaitTreeSynchronizationObject> WaitTreeSynchronizationObject::ma
 std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeSynchronizationObject::GetChildren() const {
 std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeSynchronizationObject::GetChildren() const {
     std::vector<std::unique_ptr<WaitTreeItem>> list;
     std::vector<std::unique_ptr<WaitTreeItem>> list;
 
 
-    const auto& threads = object.GetWaitingThreads();
+    const auto& threads = object.GetWaitingThreadsForDebugging();
     if (threads.empty()) {
     if (threads.empty()) {
         list.push_back(std::make_unique<WaitTreeText>(tr("waited by no thread")));
         list.push_back(std::make_unique<WaitTreeText>(tr("waited by no thread")));
     } else {
     } else {
@@ -211,8 +212,8 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeSynchronizationObject::GetChi
     return list;
     return list;
 }
 }
 
 
-WaitTreeObjectList::WaitTreeObjectList(
-    const std::vector<std::shared_ptr<Kernel::SynchronizationObject>>& list, bool w_all)
+WaitTreeObjectList::WaitTreeObjectList(const std::vector<Kernel::KSynchronizationObject*>& list,
+                                       bool w_all)
     : object_list(list), wait_all(w_all) {}
     : object_list(list), wait_all(w_all) {}
 
 
 WaitTreeObjectList::~WaitTreeObjectList() = default;
 WaitTreeObjectList::~WaitTreeObjectList() = default;
@@ -367,8 +368,8 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const {
     }
     }
 
 
     if (thread.GetStatus() == Kernel::ThreadStatus::WaitSynch) {
     if (thread.GetStatus() == Kernel::ThreadStatus::WaitSynch) {
-        list.push_back(std::make_unique<WaitTreeObjectList>(thread.GetSynchronizationObjects(),
-                                                            thread.IsWaitingSync()));
+        list.push_back(std::make_unique<WaitTreeObjectList>(thread.GetWaitObjectsForDebugging(),
+                                                            thread.IsCancellable()));
     }
     }
 
 
     list.push_back(std::make_unique<WaitTreeCallstack>(thread));
     list.push_back(std::make_unique<WaitTreeCallstack>(thread));
@@ -380,7 +381,7 @@ WaitTreeEvent::WaitTreeEvent(const Kernel::ReadableEvent& object)
     : WaitTreeSynchronizationObject(object) {}
     : WaitTreeSynchronizationObject(object) {}
 WaitTreeEvent::~WaitTreeEvent() = default;
 WaitTreeEvent::~WaitTreeEvent() = default;
 
 
-WaitTreeThreadList::WaitTreeThreadList(const std::vector<std::shared_ptr<Kernel::Thread>>& list)
+WaitTreeThreadList::WaitTreeThreadList(const std::vector<Kernel::Thread*>& list)
     : thread_list(list) {}
     : thread_list(list) {}
 WaitTreeThreadList::~WaitTreeThreadList() = default;
 WaitTreeThreadList::~WaitTreeThreadList() = default;
 
 

+ 8 - 9
src/yuzu/debugger/wait_tree.h

@@ -18,8 +18,8 @@ class EmuThread;
 
 
 namespace Kernel {
 namespace Kernel {
 class HandleTable;
 class HandleTable;
+class KSynchronizationObject;
 class ReadableEvent;
 class ReadableEvent;
-class SynchronizationObject;
 class Thread;
 class Thread;
 } // namespace Kernel
 } // namespace Kernel
 
 
@@ -102,30 +102,29 @@ private:
 class WaitTreeSynchronizationObject : public WaitTreeExpandableItem {
 class WaitTreeSynchronizationObject : public WaitTreeExpandableItem {
     Q_OBJECT
     Q_OBJECT
 public:
 public:
-    explicit WaitTreeSynchronizationObject(const Kernel::SynchronizationObject& object);
+    explicit WaitTreeSynchronizationObject(const Kernel::KSynchronizationObject& object);
     ~WaitTreeSynchronizationObject() override;
     ~WaitTreeSynchronizationObject() override;
 
 
     static std::unique_ptr<WaitTreeSynchronizationObject> make(
     static std::unique_ptr<WaitTreeSynchronizationObject> make(
-        const Kernel::SynchronizationObject& object);
+        const Kernel::KSynchronizationObject& object);
     QString GetText() const override;
     QString GetText() const override;
     std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
     std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
 
 
 protected:
 protected:
-    const Kernel::SynchronizationObject& object;
+    const Kernel::KSynchronizationObject& object;
 };
 };
 
 
 class WaitTreeObjectList : public WaitTreeExpandableItem {
 class WaitTreeObjectList : public WaitTreeExpandableItem {
     Q_OBJECT
     Q_OBJECT
 public:
 public:
-    WaitTreeObjectList(const std::vector<std::shared_ptr<Kernel::SynchronizationObject>>& list,
-                       bool wait_all);
+    WaitTreeObjectList(const std::vector<Kernel::KSynchronizationObject*>& list, bool wait_all);
     ~WaitTreeObjectList() override;
     ~WaitTreeObjectList() override;
 
 
     QString GetText() const override;
     QString GetText() const override;
     std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
     std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
 
 
 private:
 private:
-    const std::vector<std::shared_ptr<Kernel::SynchronizationObject>>& object_list;
+    const std::vector<Kernel::KSynchronizationObject*>& object_list;
     bool wait_all;
     bool wait_all;
 };
 };
 
 
@@ -150,14 +149,14 @@ public:
 class WaitTreeThreadList : public WaitTreeExpandableItem {
 class WaitTreeThreadList : public WaitTreeExpandableItem {
     Q_OBJECT
     Q_OBJECT
 public:
 public:
-    explicit WaitTreeThreadList(const std::vector<std::shared_ptr<Kernel::Thread>>& list);
+    explicit WaitTreeThreadList(const std::vector<Kernel::Thread*>& list);
     ~WaitTreeThreadList() override;
     ~WaitTreeThreadList() override;
 
 
     QString GetText() const override;
     QString GetText() const override;
     std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
     std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
 
 
 private:
 private:
-    const std::vector<std::shared_ptr<Kernel::Thread>>& thread_list;
+    const std::vector<Kernel::Thread*>& thread_list;
 };
 };
 
 
 class WaitTreeModel : public QAbstractItemModel {
 class WaitTreeModel : public QAbstractItemModel {