kernel: remove TimeManager
This commit is contained in:
parent
67c0d714c5
commit
c770f25ccb
11 changed files with 33 additions and 117 deletions
|
@ -294,8 +294,6 @@ add_library(core STATIC
|
||||||
hle/kernel/svc_common.h
|
hle/kernel/svc_common.h
|
||||||
hle/kernel/svc_types.h
|
hle/kernel/svc_types.h
|
||||||
hle/kernel/svc_wrap.h
|
hle/kernel/svc_wrap.h
|
||||||
hle/kernel/time_manager.cpp
|
|
||||||
hle/kernel/time_manager.h
|
|
||||||
hle/result.h
|
hle/result.h
|
||||||
hle/service/acc/acc.cpp
|
hle/service/acc/acc.cpp
|
||||||
hle/service/acc/acc.h
|
hle/service/acc/acc.h
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include "core/hle/kernel/k_thread_queue.h"
|
#include "core/hle/kernel/k_thread_queue.h"
|
||||||
#include "core/hle/kernel/kernel.h"
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/kernel/svc_results.h"
|
#include "core/hle/kernel/svc_results.h"
|
||||||
#include "core/hle/kernel/time_manager.h"
|
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
|
@ -5,15 +5,13 @@
|
||||||
#include "core/core_timing.h"
|
#include "core/core_timing.h"
|
||||||
#include "core/hle/kernel/k_hardware_timer.h"
|
#include "core/hle/kernel/k_hardware_timer.h"
|
||||||
#include "core/hle/kernel/k_scheduler.h"
|
#include "core/hle/kernel/k_scheduler.h"
|
||||||
#include "core/hle/kernel/time_manager.h"
|
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
void KHardwareTimer::Initialize() {
|
void KHardwareTimer::Initialize() {
|
||||||
// Create the timing callback to register with CoreTiming.
|
// Create the timing callback to register with CoreTiming.
|
||||||
m_event_type = Core::Timing::CreateEvent(
|
m_event_type = Core::Timing::CreateEvent(
|
||||||
"KHardwareTimer::Callback",
|
"KHardwareTimer::Callback", [](std::uintptr_t timer_handle, s64, std::chrono::nanoseconds) {
|
||||||
[this](std::uintptr_t timer_handle, s64, std::chrono::nanoseconds) {
|
|
||||||
reinterpret_cast<KHardwareTimer*>(timer_handle)->DoTask();
|
reinterpret_cast<KHardwareTimer*>(timer_handle)->DoTask();
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
});
|
});
|
||||||
|
@ -21,6 +19,7 @@ void KHardwareTimer::Initialize() {
|
||||||
|
|
||||||
void KHardwareTimer::Finalize() {
|
void KHardwareTimer::Finalize() {
|
||||||
this->DisableInterrupt();
|
this->DisableInterrupt();
|
||||||
|
m_event_type.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void KHardwareTimer::DoTask() {
|
void KHardwareTimer::DoTask() {
|
||||||
|
@ -64,7 +63,7 @@ void KHardwareTimer::DisableInterrupt() {
|
||||||
m_wakeup_time = std::numeric_limits<s64>::max();
|
m_wakeup_time = std::numeric_limits<s64>::max();
|
||||||
}
|
}
|
||||||
|
|
||||||
s64 KHardwareTimer::GetTick() {
|
s64 KHardwareTimer::GetTick() const {
|
||||||
return m_kernel.System().CoreTiming().GetGlobalTimeNs().count();
|
return m_kernel.System().CoreTiming().GetGlobalTimeNs().count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,10 +19,14 @@ public:
|
||||||
void Initialize();
|
void Initialize();
|
||||||
void Finalize();
|
void Finalize();
|
||||||
|
|
||||||
s64 GetCount() {
|
s64 GetCount() const {
|
||||||
return GetTick();
|
return GetTick();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RegisterTask(KTimerTask* task, s64 time_from_now) {
|
||||||
|
this->RegisterAbsoluteTask(task, GetTick() + time_from_now);
|
||||||
|
}
|
||||||
|
|
||||||
void RegisterAbsoluteTask(KTimerTask* task, s64 task_time) {
|
void RegisterAbsoluteTask(KTimerTask* task, s64 task_time) {
|
||||||
KScopedDisableDispatch dd{m_kernel};
|
KScopedDisableDispatch dd{m_kernel};
|
||||||
KScopedSpinLock lk{this->GetLock()};
|
KScopedSpinLock lk{this->GetLock()};
|
||||||
|
@ -38,7 +42,7 @@ private:
|
||||||
void EnableInterrupt(s64 wakeup_time);
|
void EnableInterrupt(s64 wakeup_time);
|
||||||
void DisableInterrupt();
|
void DisableInterrupt();
|
||||||
bool GetInterruptEnabled();
|
bool GetInterruptEnabled();
|
||||||
s64 GetTick();
|
s64 GetTick() const;
|
||||||
void DoTask();
|
void DoTask();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/hle/kernel/global_scheduler_context.h"
|
#include "core/hle/kernel/global_scheduler_context.h"
|
||||||
|
#include "core/hle/kernel/k_hardware_timer.h"
|
||||||
#include "core/hle/kernel/k_thread.h"
|
#include "core/hle/kernel/k_thread.h"
|
||||||
#include "core/hle/kernel/kernel.h"
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/kernel/time_manager.h"
|
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ public:
|
||||||
~KScopedSchedulerLockAndSleep() {
|
~KScopedSchedulerLockAndSleep() {
|
||||||
// Register the sleep.
|
// Register the sleep.
|
||||||
if (timeout_tick > 0) {
|
if (timeout_tick > 0) {
|
||||||
kernel.TimeManager().ScheduleTimeEvent(thread, timeout_tick);
|
kernel.HardwareTimer().RegisterTask(thread, timeout_tick);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unlock the scheduler.
|
// Unlock the scheduler.
|
||||||
|
|
|
@ -662,7 +662,7 @@ private:
|
||||||
union SyncObjectBuffer {
|
union SyncObjectBuffer {
|
||||||
std::array<KSynchronizationObject*, Svc::ArgumentHandleCountMax> sync_objects{};
|
std::array<KSynchronizationObject*, Svc::ArgumentHandleCountMax> sync_objects{};
|
||||||
std::array<Handle,
|
std::array<Handle,
|
||||||
Svc::ArgumentHandleCountMax * (sizeof(KSynchronizationObject*) / sizeof(Handle))>
|
Svc::ArgumentHandleCountMax*(sizeof(KSynchronizationObject*) / sizeof(Handle))>
|
||||||
handles;
|
handles;
|
||||||
constexpr SyncObjectBuffer() {}
|
constexpr SyncObjectBuffer() {}
|
||||||
};
|
};
|
||||||
|
@ -683,8 +683,10 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires(std::same_as<T, KThread> || std::same_as<T, RedBlackKeyType>)
|
requires(
|
||||||
static constexpr int Compare(const T& lhs, const KThread& rhs) {
|
std::same_as<T, KThread> ||
|
||||||
|
std::same_as<T, RedBlackKeyType>) static constexpr int Compare(const T& lhs,
|
||||||
|
const KThread& rhs) {
|
||||||
const u64 l_key = lhs.GetConditionVariableKey();
|
const u64 l_key = lhs.GetConditionVariableKey();
|
||||||
const u64 r_key = rhs.GetConditionVariableKey();
|
const u64 r_key = rhs.GetConditionVariableKey();
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "core/hle/kernel/k_hardware_timer.h"
|
||||||
#include "core/hle/kernel/k_thread_queue.h"
|
#include "core/hle/kernel/k_thread_queue.h"
|
||||||
#include "core/hle/kernel/kernel.h"
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/kernel/time_manager.h"
|
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ void KThreadQueue::EndWait(KThread* waiting_thread, Result wait_result) {
|
||||||
waiting_thread->ClearWaitQueue();
|
waiting_thread->ClearWaitQueue();
|
||||||
|
|
||||||
// Cancel the thread task.
|
// Cancel the thread task.
|
||||||
kernel.TimeManager().UnscheduleTimeEvent(waiting_thread);
|
kernel.HardwareTimer().CancelTask(waiting_thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KThreadQueue::CancelWait(KThread* waiting_thread, Result wait_result, bool cancel_timer_task) {
|
void KThreadQueue::CancelWait(KThread* waiting_thread, Result wait_result, bool cancel_timer_task) {
|
||||||
|
@ -37,7 +37,7 @@ void KThreadQueue::CancelWait(KThread* waiting_thread, Result wait_result, bool
|
||||||
|
|
||||||
// Cancel the thread task.
|
// Cancel the thread task.
|
||||||
if (cancel_timer_task) {
|
if (cancel_timer_task) {
|
||||||
kernel.TimeManager().UnscheduleTimeEvent(waiting_thread);
|
kernel.HardwareTimer().CancelTask(waiting_thread);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "core/hle/kernel/k_client_port.h"
|
#include "core/hle/kernel/k_client_port.h"
|
||||||
#include "core/hle/kernel/k_dynamic_resource_manager.h"
|
#include "core/hle/kernel/k_dynamic_resource_manager.h"
|
||||||
#include "core/hle/kernel/k_handle_table.h"
|
#include "core/hle/kernel/k_handle_table.h"
|
||||||
|
#include "core/hle/kernel/k_hardware_timer.h"
|
||||||
#include "core/hle/kernel/k_memory_layout.h"
|
#include "core/hle/kernel/k_memory_layout.h"
|
||||||
#include "core/hle/kernel/k_memory_manager.h"
|
#include "core/hle/kernel/k_memory_manager.h"
|
||||||
#include "core/hle/kernel/k_page_buffer.h"
|
#include "core/hle/kernel/k_page_buffer.h"
|
||||||
|
@ -39,7 +40,6 @@
|
||||||
#include "core/hle/kernel/kernel.h"
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/kernel/physical_core.h"
|
#include "core/hle/kernel/physical_core.h"
|
||||||
#include "core/hle/kernel/service_thread.h"
|
#include "core/hle/kernel/service_thread.h"
|
||||||
#include "core/hle/kernel/time_manager.h"
|
|
||||||
#include "core/hle/result.h"
|
#include "core/hle/result.h"
|
||||||
#include "core/hle/service/sm/sm.h"
|
#include "core/hle/service/sm/sm.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
@ -55,7 +55,7 @@ struct KernelCore::Impl {
|
||||||
static constexpr size_t ReservedDynamicPageCount = 64;
|
static constexpr size_t ReservedDynamicPageCount = 64;
|
||||||
|
|
||||||
explicit Impl(Core::System& system_, KernelCore& kernel_)
|
explicit Impl(Core::System& system_, KernelCore& kernel_)
|
||||||
: time_manager{system_}, service_threads_manager{1, "ServiceThreadsManager"},
|
: service_threads_manager{1, "ServiceThreadsManager"},
|
||||||
service_thread_barrier{2}, system{system_} {}
|
service_thread_barrier{2}, system{system_} {}
|
||||||
|
|
||||||
void SetMulticore(bool is_multi) {
|
void SetMulticore(bool is_multi) {
|
||||||
|
@ -63,6 +63,9 @@ struct KernelCore::Impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Initialize(KernelCore& kernel) {
|
void Initialize(KernelCore& kernel) {
|
||||||
|
hardware_timer = std::make_unique<Kernel::KHardwareTimer>(kernel);
|
||||||
|
hardware_timer->Initialize();
|
||||||
|
|
||||||
global_object_list_container = std::make_unique<KAutoObjectWithListContainer>(kernel);
|
global_object_list_container = std::make_unique<KAutoObjectWithListContainer>(kernel);
|
||||||
global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel);
|
global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel);
|
||||||
global_handle_table = std::make_unique<Kernel::KHandleTable>(kernel);
|
global_handle_table = std::make_unique<Kernel::KHandleTable>(kernel);
|
||||||
|
@ -193,6 +196,9 @@ struct KernelCore::Impl {
|
||||||
// Ensure that the object list container is finalized and properly shutdown.
|
// Ensure that the object list container is finalized and properly shutdown.
|
||||||
global_object_list_container->Finalize();
|
global_object_list_container->Finalize();
|
||||||
global_object_list_container.reset();
|
global_object_list_container.reset();
|
||||||
|
|
||||||
|
hardware_timer->Finalize();
|
||||||
|
hardware_timer.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CloseServices() {
|
void CloseServices() {
|
||||||
|
@ -832,7 +838,7 @@ struct KernelCore::Impl {
|
||||||
std::vector<KProcess*> process_list;
|
std::vector<KProcess*> process_list;
|
||||||
std::atomic<KProcess*> current_process{};
|
std::atomic<KProcess*> current_process{};
|
||||||
std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context;
|
std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context;
|
||||||
Kernel::TimeManager time_manager;
|
std::unique_ptr<Kernel::KHardwareTimer> hardware_timer;
|
||||||
|
|
||||||
Init::KSlabResourceCounts slab_resource_counts{};
|
Init::KSlabResourceCounts slab_resource_counts{};
|
||||||
KResourceLimit* system_resource_limit{};
|
KResourceLimit* system_resource_limit{};
|
||||||
|
@ -1019,12 +1025,8 @@ Kernel::KScheduler* KernelCore::CurrentScheduler() {
|
||||||
return impl->schedulers[core_id].get();
|
return impl->schedulers[core_id].get();
|
||||||
}
|
}
|
||||||
|
|
||||||
Kernel::TimeManager& KernelCore::TimeManager() {
|
Kernel::KHardwareTimer& KernelCore::HardwareTimer() {
|
||||||
return impl->time_manager;
|
return *impl->hardware_timer;
|
||||||
}
|
|
||||||
|
|
||||||
const Kernel::TimeManager& KernelCore::TimeManager() const {
|
|
||||||
return impl->time_manager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() {
|
Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() {
|
||||||
|
|
|
@ -39,6 +39,7 @@ class KDynamicPageManager;
|
||||||
class KEvent;
|
class KEvent;
|
||||||
class KEventInfo;
|
class KEventInfo;
|
||||||
class KHandleTable;
|
class KHandleTable;
|
||||||
|
class KHardwareTimer;
|
||||||
class KLinkedListNode;
|
class KLinkedListNode;
|
||||||
class KMemoryLayout;
|
class KMemoryLayout;
|
||||||
class KMemoryManager;
|
class KMemoryManager;
|
||||||
|
@ -63,7 +64,6 @@ class KCodeMemory;
|
||||||
class PhysicalCore;
|
class PhysicalCore;
|
||||||
class ServiceThread;
|
class ServiceThread;
|
||||||
class Synchronization;
|
class Synchronization;
|
||||||
class TimeManager;
|
|
||||||
|
|
||||||
using ServiceInterfaceFactory =
|
using ServiceInterfaceFactory =
|
||||||
std::function<KClientPort&(Service::SM::ServiceManager&, Core::System&)>;
|
std::function<KClientPort&(Service::SM::ServiceManager&, Core::System&)>;
|
||||||
|
@ -175,11 +175,8 @@ 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 TimeManager Interface.
|
/// Gets the an instance of the hardware timer.
|
||||||
Kernel::TimeManager& TimeManager();
|
Kernel::KHardwareTimer& HardwareTimer();
|
||||||
|
|
||||||
/// Gets the an instance of the TimeManager Interface.
|
|
||||||
const Kernel::TimeManager& TimeManager() const;
|
|
||||||
|
|
||||||
/// Stops execution of 'id' core, in order to reschedule a new thread.
|
/// Stops execution of 'id' core, in order to reschedule a new thread.
|
||||||
void PrepareReschedule(std::size_t id);
|
void PrepareReschedule(std::size_t id);
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#include "common/assert.h"
|
|
||||||
#include "core/core.h"
|
|
||||||
#include "core/core_timing.h"
|
|
||||||
#include "core/hle/kernel/k_scheduler.h"
|
|
||||||
#include "core/hle/kernel/k_thread.h"
|
|
||||||
#include "core/hle/kernel/time_manager.h"
|
|
||||||
|
|
||||||
namespace Kernel {
|
|
||||||
|
|
||||||
TimeManager::TimeManager(Core::System& system_) : system{system_} {
|
|
||||||
time_manager_event_type = Core::Timing::CreateEvent(
|
|
||||||
"Kernel::TimeManagerCallback",
|
|
||||||
[this](std::uintptr_t thread_handle, s64 time,
|
|
||||||
std::chrono::nanoseconds) -> std::optional<std::chrono::nanoseconds> {
|
|
||||||
KThread* thread = reinterpret_cast<KThread*>(thread_handle);
|
|
||||||
{
|
|
||||||
KScopedSchedulerLock sl(system.Kernel());
|
|
||||||
thread->OnTimer();
|
|
||||||
}
|
|
||||||
return std::nullopt;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimeManager::ScheduleTimeEvent(KThread* thread, s64 nanoseconds) {
|
|
||||||
std::scoped_lock lock{mutex};
|
|
||||||
if (nanoseconds > 0) {
|
|
||||||
ASSERT(thread);
|
|
||||||
ASSERT(thread->GetState() != ThreadState::Runnable);
|
|
||||||
system.CoreTiming().ScheduleEvent(std::chrono::nanoseconds{nanoseconds},
|
|
||||||
time_manager_event_type,
|
|
||||||
reinterpret_cast<uintptr_t>(thread));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimeManager::UnscheduleTimeEvent(KThread* thread) {
|
|
||||||
std::scoped_lock lock{mutex};
|
|
||||||
system.CoreTiming().UnscheduleEvent(time_manager_event_type,
|
|
||||||
reinterpret_cast<uintptr_t>(thread));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Kernel
|
|
|
@ -1,41 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <mutex>
|
|
||||||
|
|
||||||
namespace Core {
|
|
||||||
class System;
|
|
||||||
} // namespace Core
|
|
||||||
|
|
||||||
namespace Core::Timing {
|
|
||||||
struct EventType;
|
|
||||||
} // namespace Core::Timing
|
|
||||||
|
|
||||||
namespace Kernel {
|
|
||||||
|
|
||||||
class KThread;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The `TimeManager` takes care of scheduling time events on threads and executes their TimeUp
|
|
||||||
* method when the event is triggered.
|
|
||||||
*/
|
|
||||||
class TimeManager {
|
|
||||||
public:
|
|
||||||
explicit TimeManager(Core::System& system);
|
|
||||||
|
|
||||||
/// Schedule a time event on `timetask` thread that will expire in 'nanoseconds'
|
|
||||||
void ScheduleTimeEvent(KThread* time_task, s64 nanoseconds);
|
|
||||||
|
|
||||||
/// Unschedule an existing time event
|
|
||||||
void UnscheduleTimeEvent(KThread* thread);
|
|
||||||
|
|
||||||
private:
|
|
||||||
Core::System& system;
|
|
||||||
std::shared_ptr<Core::Timing::EventType> time_manager_event_type;
|
|
||||||
std::mutex mutex;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Kernel
|
|
Loading…
Reference in a new issue