mirror of
https://github.com/PabloMK7/citra.git
synced 2024-11-20 14:34:17 +00:00
kernel/timer: add TimerManager for timer system states
This commit is contained in:
parent
20ae37ba4f
commit
e5b93741d3
4 changed files with 49 additions and 28 deletions
|
@ -22,12 +22,11 @@ KernelSystem::KernelSystem(u32 system_mode) {
|
||||||
|
|
||||||
resource_limits = std::make_unique<ResourceLimitList>(*this);
|
resource_limits = std::make_unique<ResourceLimitList>(*this);
|
||||||
thread_manager = std::make_unique<ThreadManager>();
|
thread_manager = std::make_unique<ThreadManager>();
|
||||||
Kernel::TimersInit();
|
timer_manager = std::make_unique<TimerManager>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Shutdown the kernel
|
/// Shutdown the kernel
|
||||||
KernelSystem::~KernelSystem() {
|
KernelSystem::~KernelSystem() {
|
||||||
Kernel::TimersShutdown();
|
|
||||||
Kernel::MemoryShutdown();
|
Kernel::MemoryShutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,4 +58,12 @@ const ThreadManager& KernelSystem::GetThreadManager() const {
|
||||||
return *thread_manager;
|
return *thread_manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TimerManager& KernelSystem::GetTimerManager() {
|
||||||
|
return *timer_manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TimerManager& KernelSystem::GetTimerManager() const {
|
||||||
|
return *timer_manager;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -29,6 +29,7 @@ class ServerSession;
|
||||||
class ResourceLimitList;
|
class ResourceLimitList;
|
||||||
class SharedMemory;
|
class SharedMemory;
|
||||||
class ThreadManager;
|
class ThreadManager;
|
||||||
|
class TimerManager;
|
||||||
|
|
||||||
enum class ResetType {
|
enum class ResetType {
|
||||||
OneShot,
|
OneShot,
|
||||||
|
@ -191,6 +192,9 @@ public:
|
||||||
ThreadManager& GetThreadManager();
|
ThreadManager& GetThreadManager();
|
||||||
const ThreadManager& GetThreadManager() const;
|
const ThreadManager& GetThreadManager() const;
|
||||||
|
|
||||||
|
TimerManager& GetTimerManager();
|
||||||
|
const TimerManager& GetTimerManager() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<ResourceLimitList> resource_limits;
|
std::unique_ptr<ResourceLimitList> resource_limits;
|
||||||
std::atomic<u32> next_object_id{0};
|
std::atomic<u32> next_object_id{0};
|
||||||
|
@ -205,6 +209,7 @@ private:
|
||||||
SharedPtr<Process> current_process;
|
SharedPtr<Process> current_process;
|
||||||
|
|
||||||
std::unique_ptr<ThreadManager> thread_manager;
|
std::unique_ptr<ThreadManager> thread_manager;
|
||||||
|
std::unique_ptr<TimerManager> timer_manager;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/core_timing.h"
|
|
||||||
#include "core/hle/kernel/handle_table.h"
|
#include "core/hle/kernel/handle_table.h"
|
||||||
#include "core/hle/kernel/object.h"
|
#include "core/hle/kernel/object.h"
|
||||||
#include "core/hle/kernel/thread.h"
|
#include "core/hle/kernel/thread.h"
|
||||||
|
@ -14,16 +13,10 @@
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
/// The event type of the generic timer callback event
|
Timer::Timer(KernelSystem& kernel) : WaitObject(kernel), timer_manager(kernel.GetTimerManager()) {}
|
||||||
static CoreTiming::EventType* timer_callback_event_type = nullptr;
|
|
||||||
|
|
||||||
static u64 next_timer_callback_id;
|
|
||||||
static std::unordered_map<u64, Timer*> timer_callback_table;
|
|
||||||
|
|
||||||
Timer::Timer(KernelSystem& kernel) : WaitObject(kernel) {}
|
|
||||||
Timer::~Timer() {
|
Timer::~Timer() {
|
||||||
Cancel();
|
Cancel();
|
||||||
timer_callback_table.erase(callback_id);
|
timer_manager.timer_callback_table.erase(callback_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<Timer> KernelSystem::CreateTimer(ResetType reset_type, std::string name) {
|
SharedPtr<Timer> KernelSystem::CreateTimer(ResetType reset_type, std::string name) {
|
||||||
|
@ -34,8 +27,8 @@ SharedPtr<Timer> KernelSystem::CreateTimer(ResetType reset_type, std::string nam
|
||||||
timer->name = std::move(name);
|
timer->name = std::move(name);
|
||||||
timer->initial_delay = 0;
|
timer->initial_delay = 0;
|
||||||
timer->interval_delay = 0;
|
timer->interval_delay = 0;
|
||||||
timer->callback_id = ++next_timer_callback_id;
|
timer->callback_id = ++timer_manager->next_timer_callback_id;
|
||||||
timer_callback_table[timer->callback_id] = timer.get();
|
timer_manager->timer_callback_table[timer->callback_id] = timer.get();
|
||||||
|
|
||||||
return timer;
|
return timer;
|
||||||
}
|
}
|
||||||
|
@ -62,12 +55,13 @@ void Timer::Set(s64 initial, s64 interval) {
|
||||||
// Immediately invoke the callback
|
// Immediately invoke the callback
|
||||||
Signal(0);
|
Signal(0);
|
||||||
} else {
|
} else {
|
||||||
CoreTiming::ScheduleEvent(nsToCycles(initial), timer_callback_event_type, callback_id);
|
CoreTiming::ScheduleEvent(nsToCycles(initial), timer_manager.timer_callback_event_type,
|
||||||
|
callback_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Timer::Cancel() {
|
void Timer::Cancel() {
|
||||||
CoreTiming::UnscheduleEvent(timer_callback_event_type, callback_id);
|
CoreTiming::UnscheduleEvent(timer_manager.timer_callback_event_type, callback_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Timer::Clear() {
|
void Timer::Clear() {
|
||||||
|
@ -92,12 +86,12 @@ void Timer::Signal(s64 cycles_late) {
|
||||||
if (interval_delay != 0) {
|
if (interval_delay != 0) {
|
||||||
// Reschedule the timer with the interval delay
|
// Reschedule the timer with the interval delay
|
||||||
CoreTiming::ScheduleEvent(nsToCycles(interval_delay) - cycles_late,
|
CoreTiming::ScheduleEvent(nsToCycles(interval_delay) - cycles_late,
|
||||||
timer_callback_event_type, callback_id);
|
timer_manager.timer_callback_event_type, callback_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The timer callback event, called when a timer is fired
|
/// The timer callback event, called when a timer is fired
|
||||||
static void TimerCallback(u64 callback_id, s64 cycles_late) {
|
void TimerManager::TimerCallback(u64 callback_id, s64 cycles_late) {
|
||||||
SharedPtr<Timer> timer = timer_callback_table.at(callback_id);
|
SharedPtr<Timer> timer = timer_callback_table.at(callback_id);
|
||||||
|
|
||||||
if (timer == nullptr) {
|
if (timer == nullptr) {
|
||||||
|
@ -108,12 +102,11 @@ static void TimerCallback(u64 callback_id, s64 cycles_late) {
|
||||||
timer->Signal(cycles_late);
|
timer->Signal(cycles_late);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimersInit() {
|
TimerManager::TimerManager() {
|
||||||
next_timer_callback_id = 0;
|
timer_callback_event_type =
|
||||||
timer_callback_table.clear();
|
CoreTiming::RegisterEvent("TimerCallback", [this](u64 thread_id, s64 cycle_late) {
|
||||||
timer_callback_event_type = CoreTiming::RegisterEvent("TimerCallback", TimerCallback);
|
TimerCallback(thread_id, cycle_late);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimersShutdown() {}
|
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -5,11 +5,30 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
#include "core/core_timing.h"
|
||||||
#include "core/hle/kernel/object.h"
|
#include "core/hle/kernel/object.h"
|
||||||
#include "core/hle/kernel/wait_object.h"
|
#include "core/hle/kernel/wait_object.h"
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
|
class TimerManager {
|
||||||
|
public:
|
||||||
|
TimerManager();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// The timer callback event, called when a timer is fired
|
||||||
|
void TimerCallback(u64 callback_id, s64 cycles_late);
|
||||||
|
|
||||||
|
/// The event type of the generic timer callback event
|
||||||
|
CoreTiming::EventType* timer_callback_event_type = nullptr;
|
||||||
|
|
||||||
|
u64 next_timer_callback_id = 0;
|
||||||
|
std::unordered_map<u64, Timer*> timer_callback_table;
|
||||||
|
|
||||||
|
friend class Timer;
|
||||||
|
friend class KernelSystem;
|
||||||
|
};
|
||||||
|
|
||||||
class Timer final : public WaitObject {
|
class Timer final : public WaitObject {
|
||||||
public:
|
public:
|
||||||
std::string GetTypeName() const override {
|
std::string GetTypeName() const override {
|
||||||
|
@ -74,12 +93,9 @@ private:
|
||||||
/// ID used as userdata to reference this object when inserting into the CoreTiming queue.
|
/// ID used as userdata to reference this object when inserting into the CoreTiming queue.
|
||||||
u64 callback_id;
|
u64 callback_id;
|
||||||
|
|
||||||
|
TimerManager& timer_manager;
|
||||||
|
|
||||||
friend class KernelSystem;
|
friend class KernelSystem;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Initializes the required variables for timers
|
|
||||||
void TimersInit();
|
|
||||||
/// Tears down the timer variables
|
|
||||||
void TimersShutdown();
|
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
Loading…
Reference in a new issue