forked from suyu/suyu
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/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.h
|
||||||
hle/kernel/transfer_memory.cpp
|
hle/kernel/transfer_memory.cpp
|
||||||
hle/kernel/transfer_memory.h
|
hle/kernel/transfer_memory.h
|
||||||
hle/kernel/vm_manager.cpp
|
hle/kernel/vm_manager.cpp
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "core/hle/kernel/scheduler.h"
|
#include "core/hle/kernel/scheduler.h"
|
||||||
#include "core/hle/kernel/synchronization.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/lock.h"
|
#include "core/hle/lock.h"
|
||||||
#include "core/hle/result.h"
|
#include "core/hle/result.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
@ -100,7 +101,7 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] s64 cycles_
|
||||||
|
|
||||||
struct KernelCore::Impl {
|
struct KernelCore::Impl {
|
||||||
explicit Impl(Core::System& system, KernelCore& kernel)
|
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) {
|
void Initialize(KernelCore& kernel) {
|
||||||
Shutdown();
|
Shutdown();
|
||||||
|
@ -238,6 +239,7 @@ struct KernelCore::Impl {
|
||||||
Process* current_process = nullptr;
|
Process* current_process = nullptr;
|
||||||
Kernel::GlobalScheduler global_scheduler;
|
Kernel::GlobalScheduler global_scheduler;
|
||||||
Kernel::Synchronization synchronization;
|
Kernel::Synchronization synchronization;
|
||||||
|
Kernel::TimeManager time_manager;
|
||||||
|
|
||||||
std::shared_ptr<ResourceLimit> system_resource_limit;
|
std::shared_ptr<ResourceLimit> system_resource_limit;
|
||||||
|
|
||||||
|
@ -337,6 +339,14 @@ const Kernel::Synchronization& KernelCore::Synchronization() const {
|
||||||
return impl->synchronization;
|
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() {
|
Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() {
|
||||||
return *impl->exclusive_monitor;
|
return *impl->exclusive_monitor;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ class ResourceLimit;
|
||||||
class Scheduler;
|
class Scheduler;
|
||||||
class Synchronization;
|
class Synchronization;
|
||||||
class Thread;
|
class Thread;
|
||||||
|
class TimeManager;
|
||||||
|
|
||||||
/// Represents a single instance of the kernel.
|
/// Represents a single instance of the kernel.
|
||||||
class KernelCore {
|
class KernelCore {
|
||||||
|
@ -107,6 +108,12 @@ public:
|
||||||
/// Gets the an instance of the Synchronization Interface.
|
/// Gets the an instance of the Synchronization Interface.
|
||||||
const Kernel::Synchronization& Synchronization() const;
|
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.
|
/// Stops execution of 'id' core, in order to reschedule a new thread.
|
||||||
void PrepareReschedule(std::size_t id);
|
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