diff options
| author | bunnei <bunneidev@gmail.com> | 2020-12-03 21:56:02 -0800 | 
|---|---|---|
| committer | bunnei <bunneidev@gmail.com> | 2020-12-06 00:03:24 -0800 | 
| commit | 4756cb203e8ef09377988eb1b49ca20ef45f4492 (patch) | |
| tree | 69aed28dbf048dea702665e68797f14c20650276 /src/core/hle | |
| parent | 8d3e06349e12e7de17c334619f1f986792d1de4b (diff) | |
hle: kernel: Separate KScopedSchedulerLockAndSleep from k_scheduler.
Diffstat (limited to 'src/core/hle')
| -rw-r--r-- | src/core/hle/kernel/address_arbiter.cpp | 5 | ||||
| -rw-r--r-- | src/core/hle/kernel/global_scheduler_context.cpp | 8 | ||||
| -rw-r--r-- | src/core/hle/kernel/global_scheduler_context.h | 10 | ||||
| -rw-r--r-- | src/core/hle/kernel/hle_ipc.cpp | 8 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_scheduler.cpp | 25 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_scheduler.h | 19 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h | 56 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 3 | ||||
| -rw-r--r-- | src/core/hle/kernel/synchronization.cpp | 3 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 3 | 
10 files changed, 71 insertions, 69 deletions
| diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index bc32be18b..ac4913173 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -13,6 +13,7 @@  #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/thread.h"  #include "core/hle/kernel/time_manager.h" @@ -157,7 +158,7 @@ ResultCode AddressArbiter::WaitForAddressIfLessThan(VAddr address, s32 value, s6      Handle event_handle = InvalidHandle;      { -        SchedulerLockAndSleep lock(kernel, event_handle, current_thread, timeout); +        KScopedSchedulerLockAndSleep lock(kernel, event_handle, current_thread, timeout);          if (current_thread->IsPendingTermination()) {              lock.CancelSleep(); @@ -227,7 +228,7 @@ ResultCode AddressArbiter::WaitForAddressIfEqual(VAddr address, s32 value, s64 t      Handle event_handle = InvalidHandle;      { -        SchedulerLockAndSleep lock(kernel, event_handle, current_thread, timeout); +        KScopedSchedulerLockAndSleep lock(kernel, event_handle, current_thread, timeout);          if (current_thread->IsPendingTermination()) {              lock.CancelSleep(); diff --git a/src/core/hle/kernel/global_scheduler_context.cpp b/src/core/hle/kernel/global_scheduler_context.cpp index 40e9adf47..a9cb48b38 100644 --- a/src/core/hle/kernel/global_scheduler_context.cpp +++ b/src/core/hle/kernel/global_scheduler_context.cpp @@ -44,12 +44,4 @@ bool GlobalSchedulerContext::IsLocked() const {      return scheduler_lock.IsLockedByCurrentThread();  } -void GlobalSchedulerContext::Lock() { -    scheduler_lock.Lock(); -} - -void GlobalSchedulerContext::Unlock() { -    scheduler_lock.Unlock(); -} -  } // namespace Kernel diff --git a/src/core/hle/kernel/global_scheduler_context.h b/src/core/hle/kernel/global_scheduler_context.h index 40fe44cc0..39c383746 100644 --- a/src/core/hle/kernel/global_scheduler_context.h +++ b/src/core/hle/kernel/global_scheduler_context.h @@ -55,15 +55,7 @@ public:  private:      friend class SchedulerLock; - -    /// Lock the scheduler to the current thread. -    void Lock(); - -    /// Unlocks the scheduler, reselects threads, interrupts cores for rescheduling -    /// and reschedules current core if needed. -    void Unlock(); - -    using LockType = KAbstractSchedulerLock<KScheduler>; +    friend class KScopedSchedulerLockAndSleep;      KernelCore& kernel; diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 7eda89786..e75e80ad0 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -18,6 +18,7 @@  #include "core/hle/kernel/handle_table.h"  #include "core/hle/kernel/hle_ipc.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/object.h"  #include "core/hle/kernel/process.h" @@ -56,9 +57,9 @@ std::shared_ptr<WritableEvent> HLERequestContext::SleepClientThread(          writable_event = pair.writable;      } +    Handle event_handle = InvalidHandle;      { -        Handle event_handle = InvalidHandle; -        SchedulerLockAndSleep lock(kernel, event_handle, thread.get(), timeout); +        KScopedSchedulerLockAndSleep lock(kernel, event_handle, thread.get(), timeout);          thread->SetHLECallback(              [context = *this, callback](std::shared_ptr<Thread> thread) mutable -> bool {                  ThreadWakeupReason reason = thread->GetSignalingResult() == RESULT_TIMEOUT @@ -74,9 +75,8 @@ std::shared_ptr<WritableEvent> HLERequestContext::SleepClientThread(          thread->SetStatus(ThreadStatus::WaitHLEEvent);          thread->SetSynchronizationResults(nullptr, RESULT_TIMEOUT);          readable_event->AddWaitingThread(thread); -        lock.Release(); -        thread->SetHLETimeEvent(event_handle);      } +    thread->SetHLETimeEvent(event_handle);      is_thread_waiting = true; diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp index c7e2eabd4..466147498 100644 --- a/src/core/hle/kernel/k_scheduler.cpp +++ b/src/core/hle/kernel/k_scheduler.cpp @@ -14,6 +14,7 @@  #include "core/core_timing.h"  #include "core/cpu_manager.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/physical_core.h"  #include "core/hle/kernel/process.h" @@ -800,28 +801,4 @@ SchedulerLock::~SchedulerLock() {      kernel.GlobalSchedulerContext().Unlock();  } -SchedulerLockAndSleep::SchedulerLockAndSleep(KernelCore& kernel, Handle& event_handle, -                                             Thread* time_task, s64 nanoseconds) -    : SchedulerLock{kernel}, event_handle{event_handle}, time_task{time_task}, nanoseconds{ -                                                                                   nanoseconds} { -    event_handle = InvalidHandle; -} - -SchedulerLockAndSleep::~SchedulerLockAndSleep() { -    if (sleep_cancelled) { -        return; -    } -    auto& time_manager = kernel.TimeManager(); -    time_manager.ScheduleTimeEvent(event_handle, time_task, nanoseconds); -} - -void SchedulerLockAndSleep::Release() { -    if (sleep_cancelled) { -        return; -    } -    auto& time_manager = kernel.TimeManager(); -    time_manager.ScheduleTimeEvent(event_handle, time_task, nanoseconds); -    sleep_cancelled = true; -} -  } // namespace Kernel diff --git a/src/core/hle/kernel/k_scheduler.h b/src/core/hle/kernel/k_scheduler.h index 7f020d96e..5ba0f3c32 100644 --- a/src/core/hle/kernel/k_scheduler.h +++ b/src/core/hle/kernel/k_scheduler.h @@ -207,23 +207,4 @@ protected:      KernelCore& kernel;  }; -class SchedulerLockAndSleep : public SchedulerLock { -public: -    explicit SchedulerLockAndSleep(KernelCore& kernel, Handle& event_handle, Thread* time_task, -                                   s64 nanoseconds); -    ~SchedulerLockAndSleep(); - -    void CancelSleep() { -        sleep_cancelled = true; -    } - -    void Release(); - -private: -    Handle& event_handle; -    Thread* time_task; -    s64 nanoseconds; -    bool sleep_cancelled{}; -}; -  } // namespace Kernel diff --git a/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h b/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h new file mode 100644 index 000000000..f11a62216 --- /dev/null +++ b/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h @@ -0,0 +1,56 @@ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +// This file references various implementation details from Atmosphere, an open-source firmware for +// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. + +#pragma once + +#include "common/common_types.h" +#include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/thread.h" +#include "core/hle/kernel/time_manager.h" + +namespace Kernel { + +class KScopedSchedulerLockAndSleep { +private: +    KernelCore& kernel; +    s64 timeout_tick{}; +    Thread* thread{}; +    Handle* event_handle{}; + +public: +    explicit KScopedSchedulerLockAndSleep(KernelCore& kernel, Thread* t, s64 timeout) +        : kernel(kernel), timeout_tick(timeout), thread(t) { +        /* Lock the scheduler. */ +        kernel.GlobalSchedulerContext().scheduler_lock.Lock(); +    } + +    explicit KScopedSchedulerLockAndSleep(KernelCore& kernel, Handle& event_handle, Thread* t, +                                          s64 timeout) +        : kernel(kernel), event_handle(&event_handle), timeout_tick(timeout), thread(t) { +        /* Lock the scheduler. */ +        kernel.GlobalSchedulerContext().scheduler_lock.Lock(); +    } + +    ~KScopedSchedulerLockAndSleep() { +        /* Register the sleep. */ +        if (this->timeout_tick > 0) { +            auto& time_manager = kernel.TimeManager(); +            Handle handle{}; +            time_manager.ScheduleTimeEvent(event_handle ? *event_handle : handle, this->thread, +                                           this->timeout_tick); +        } + +        /* Unlock the scheduler. */ +        kernel.GlobalSchedulerContext().scheduler_lock.Unlock(); +    } + +    void CancelSleep() { +        this->timeout_tick = 0; +    } +}; + +} // namespace Kernel diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 2612a6b0d..2760a307c 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -25,6 +25,7 @@  #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/memory/memory_block.h"  #include "core/hle/kernel/memory/page_table.h" @@ -1654,7 +1655,7 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_add      Thread* current_thread = kernel.CurrentScheduler()->GetCurrentThread();      auto* const current_process = kernel.CurrentProcess();      { -        SchedulerLockAndSleep lock(kernel, event_handle, current_thread, nano_seconds); +        KScopedSchedulerLockAndSleep lock(kernel, event_handle, current_thread, nano_seconds);          const auto& handle_table = current_process->GetHandleTable();          std::shared_ptr<Thread> thread = handle_table.Get<Thread>(thread_handle);          ASSERT(thread); diff --git a/src/core/hle/kernel/synchronization.cpp b/src/core/hle/kernel/synchronization.cpp index 342fb4516..6651ad90c 100644 --- a/src/core/hle/kernel/synchronization.cpp +++ b/src/core/hle/kernel/synchronization.cpp @@ -6,6 +6,7 @@  #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" @@ -40,7 +41,7 @@ std::pair<ResultCode, Handle> Synchronization::WaitFor(      auto* const thread = kernel.CurrentScheduler()->GetCurrentThread();      Handle event_handle = InvalidHandle;      { -        SchedulerLockAndSleep lock(kernel, event_handle, thread, nano_seconds); +        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) { diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 804e07f2b..6f89238ca 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -18,6 +18,7 @@  #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/object.h"  #include "core/hle/kernel/process.h" @@ -393,7 +394,7 @@ ResultCode Thread::SetActivity(ThreadActivity value) {  ResultCode Thread::Sleep(s64 nanoseconds) {      Handle event_handle{};      { -        SchedulerLockAndSleep lock(kernel, event_handle, this, nanoseconds); +        KScopedSchedulerLockAndSleep lock(kernel, event_handle, this, nanoseconds);          SetStatus(ThreadStatus::WaitSleep);      } | 
