mirror of
https://github.com/yuzu-mirror/yuzu
synced 2024-11-23 15:53:03 +00:00
Kernel: Implement Time Manager.
This commit is contained in:
parent
179bafa7cb
commit
5c90d22f3d
5 changed files with 98 additions and 1 deletions
|
@ -187,6 +187,8 @@ add_library(core STATIC
|
|||
hle/kernel/synchronization.h
|
||||
hle/kernel/thread.cpp
|
||||
hle/kernel/thread.h
|
||||
hle/kernel/time_manager.cpp
|
||||
hle/kernel/time_manager.h
|
||||
hle/kernel/transfer_memory.cpp
|
||||
hle/kernel/transfer_memory.h
|
||||
hle/kernel/vm_manager.cpp
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "core/hle/kernel/scheduler.h"
|
||||
#include "core/hle/kernel/synchronization.h"
|
||||
#include "core/hle/kernel/thread.h"
|
||||
#include "core/hle/kernel/time_manager.h"
|
||||
#include "core/hle/lock.h"
|
||||
#include "core/hle/result.h"
|
||||
#include "core/memory.h"
|
||||
|
@ -100,7 +101,7 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] s64 cycles_
|
|||
|
||||
struct KernelCore::Impl {
|
||||
explicit Impl(Core::System& system, KernelCore& kernel)
|
||||
: system{system}, global_scheduler{kernel}, synchronization{system} {}
|
||||
: system{system}, global_scheduler{kernel}, synchronization{system}, time_manager{system} {}
|
||||
|
||||
void Initialize(KernelCore& kernel) {
|
||||
Shutdown();
|
||||
|
@ -238,6 +239,7 @@ struct KernelCore::Impl {
|
|||
Process* current_process = nullptr;
|
||||
Kernel::GlobalScheduler global_scheduler;
|
||||
Kernel::Synchronization synchronization;
|
||||
Kernel::TimeManager time_manager;
|
||||
|
||||
std::shared_ptr<ResourceLimit> system_resource_limit;
|
||||
|
||||
|
@ -337,6 +339,14 @@ const Kernel::Synchronization& KernelCore::Synchronization() const {
|
|||
return impl->synchronization;
|
||||
}
|
||||
|
||||
Kernel::TimeManager& KernelCore::TimeManager() {
|
||||
return impl->time_manager;
|
||||
}
|
||||
|
||||
const Kernel::TimeManager& KernelCore::TimeManager() const {
|
||||
return impl->time_manager;
|
||||
}
|
||||
|
||||
Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() {
|
||||
return *impl->exclusive_monitor;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ class ResourceLimit;
|
|||
class Scheduler;
|
||||
class Synchronization;
|
||||
class Thread;
|
||||
class TimeManager;
|
||||
|
||||
/// Represents a single instance of the kernel.
|
||||
class KernelCore {
|
||||
|
@ -107,6 +108,12 @@ public:
|
|||
/// Gets the an instance of the Synchronization Interface.
|
||||
const Kernel::Synchronization& Synchronization() const;
|
||||
|
||||
/// Gets the an instance of the TimeManager Interface.
|
||||
Kernel::TimeManager& TimeManager();
|
||||
|
||||
/// 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.
|
||||
void PrepareReschedule(std::size_t id);
|
||||
|
||||
|
|
42
src/core/hle/kernel/time_manager.cpp
Normal file
42
src/core/hle/kernel/time_manager.cpp
Normal file
|
@ -0,0 +1,42 @@
|
|||
// 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/core_timing.h"
|
||||
#include "core/core_timing_util.h"
|
||||
#include "core/hle/kernel/handle_table.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/kernel/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](u64 thread_handle, [[maybe_unused]] s64 cycles_late) {
|
||||
Handle proper_handle = static_cast<Handle>(thread_handle);
|
||||
std::shared_ptr<Thread> thread =
|
||||
this->system.Kernel().RetrieveThreadFromGlobalHandleTable(proper_handle);
|
||||
thread->ResumeFromWait();
|
||||
});
|
||||
}
|
||||
|
||||
void TimeManager::ScheduleTimeEvent(Handle& event_handle, Thread* timetask, s64 nanoseconds) {
|
||||
if (nanoseconds > 0) {
|
||||
ASSERT(timetask);
|
||||
event_handle = timetask->GetGlobalHandle();
|
||||
const s64 cycles = Core::Timing::nsToCycles(std::chrono::nanoseconds{nanoseconds});
|
||||
system.CoreTiming().ScheduleEvent(cycles, time_manager_event_type, event_handle);
|
||||
} else {
|
||||
event_handle = InvalidHandle;
|
||||
}
|
||||
}
|
||||
|
||||
void TimeManager::UnscheduleTimeEvent(Handle event_handle) {
|
||||
if (event_handle != InvalidHandle) {
|
||||
system.CoreTiming().UnscheduleEvent(time_manager_event_type, event_handle);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Kernel
|
36
src/core/hle/kernel/time_manager.h
Normal file
36
src/core/hle/kernel/time_manager.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
// Copyright 2020 yuzu Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "core/hle/kernel/object.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
} // namespace Core
|
||||
|
||||
namespace Core::Timing {
|
||||
struct EventType;
|
||||
} // namespace Core::Timing
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
class Thread;
|
||||
|
||||
class TimeManager {
|
||||
public:
|
||||
TimeManager(Core::System& system);
|
||||
|
||||
void ScheduleTimeEvent(Handle& event_handle, Thread* timetask, s64 nanoseconds);
|
||||
|
||||
void UnscheduleTimeEvent(Handle event_handle);
|
||||
|
||||
private:
|
||||
Core::System& system;
|
||||
std::shared_ptr<Core::Timing::EventType> time_manager_event_type;
|
||||
};
|
||||
|
||||
} // namespace Kernel
|
Loading…
Reference in a new issue