Merge pull request #2078 from lioncash/timer

kernel: Remove the Timer class
master
bunnei 2019-02-01 12:49:16 +07:00 committed by GitHub
commit 11e7c1244c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 0 additions and 259 deletions

@ -140,8 +140,6 @@ add_library(core STATIC
hle/kernel/svc_wrap.h hle/kernel/svc_wrap.h
hle/kernel/thread.cpp hle/kernel/thread.cpp
hle/kernel/thread.h hle/kernel/thread.h
hle/kernel/timer.cpp
hle/kernel/timer.h
hle/kernel/vm_manager.cpp hle/kernel/vm_manager.cpp
hle/kernel/vm_manager.h hle/kernel/vm_manager.h
hle/kernel/wait_object.cpp hle/kernel/wait_object.cpp

@ -18,7 +18,6 @@
#include "core/hle/kernel/process.h" #include "core/hle/kernel/process.h"
#include "core/hle/kernel/resource_limit.h" #include "core/hle/kernel/resource_limit.h"
#include "core/hle/kernel/thread.h" #include "core/hle/kernel/thread.h"
#include "core/hle/kernel/timer.h"
#include "core/hle/lock.h" #include "core/hle/lock.h"
#include "core/hle/result.h" #include "core/hle/result.h"
@ -86,27 +85,12 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] int cycles_
} }
} }
/// The timer callback event, called when a timer is fired
static void TimerCallback(u64 timer_handle, int cycles_late) {
const auto proper_handle = static_cast<Handle>(timer_handle);
const auto& system = Core::System::GetInstance();
SharedPtr<Timer> timer = system.Kernel().RetrieveTimerFromCallbackHandleTable(proper_handle);
if (timer == nullptr) {
LOG_CRITICAL(Kernel, "Callback fired for invalid timer {:016X}", timer_handle);
return;
}
timer->Signal(cycles_late);
}
struct KernelCore::Impl { struct KernelCore::Impl {
void Initialize(KernelCore& kernel) { void Initialize(KernelCore& kernel) {
Shutdown(); Shutdown();
InitializeSystemResourceLimit(kernel); InitializeSystemResourceLimit(kernel);
InitializeThreads(); InitializeThreads();
InitializeTimers();
} }
void Shutdown() { void Shutdown() {
@ -122,9 +106,6 @@ struct KernelCore::Impl {
thread_wakeup_callback_handle_table.Clear(); thread_wakeup_callback_handle_table.Clear();
thread_wakeup_event_type = nullptr; thread_wakeup_event_type = nullptr;
timer_callback_handle_table.Clear();
timer_callback_event_type = nullptr;
named_ports.clear(); named_ports.clear();
} }
@ -146,11 +127,6 @@ struct KernelCore::Impl {
CoreTiming::RegisterEvent("ThreadWakeupCallback", ThreadWakeupCallback); CoreTiming::RegisterEvent("ThreadWakeupCallback", ThreadWakeupCallback);
} }
void InitializeTimers() {
timer_callback_handle_table.Clear();
timer_callback_event_type = CoreTiming::RegisterEvent("TimerCallback", TimerCallback);
}
std::atomic<u32> next_object_id{0}; std::atomic<u32> next_object_id{0};
std::atomic<u64> next_process_id{Process::ProcessIDMin}; std::atomic<u64> next_process_id{Process::ProcessIDMin};
std::atomic<u64> next_thread_id{1}; std::atomic<u64> next_thread_id{1};
@ -161,12 +137,6 @@ struct KernelCore::Impl {
SharedPtr<ResourceLimit> system_resource_limit; SharedPtr<ResourceLimit> system_resource_limit;
/// The event type of the generic timer callback event
CoreTiming::EventType* timer_callback_event_type = nullptr;
// TODO(yuriks): This can be removed if Timer objects are explicitly pooled in the future,
// allowing us to simply use a pool index or similar.
Kernel::HandleTable timer_callback_handle_table;
CoreTiming::EventType* thread_wakeup_event_type = nullptr; CoreTiming::EventType* thread_wakeup_event_type = nullptr;
// TODO(yuriks): This can be removed if Thread objects are explicitly pooled in the future, // TODO(yuriks): This can be removed if Thread objects are explicitly pooled in the future,
// allowing us to simply use a pool index or similar. // allowing us to simply use a pool index or similar.
@ -198,10 +168,6 @@ SharedPtr<Thread> KernelCore::RetrieveThreadFromWakeupCallbackHandleTable(Handle
return impl->thread_wakeup_callback_handle_table.Get<Thread>(handle); return impl->thread_wakeup_callback_handle_table.Get<Thread>(handle);
} }
SharedPtr<Timer> KernelCore::RetrieveTimerFromCallbackHandleTable(Handle handle) const {
return impl->timer_callback_handle_table.Get<Timer>(handle);
}
void KernelCore::AppendNewProcess(SharedPtr<Process> process) { void KernelCore::AppendNewProcess(SharedPtr<Process> process) {
impl->process_list.push_back(std::move(process)); impl->process_list.push_back(std::move(process));
} }
@ -247,18 +213,10 @@ u64 KernelCore::CreateNewProcessID() {
return impl->next_process_id++; return impl->next_process_id++;
} }
ResultVal<Handle> KernelCore::CreateTimerCallbackHandle(const SharedPtr<Timer>& timer) {
return impl->timer_callback_handle_table.Create(timer);
}
CoreTiming::EventType* KernelCore::ThreadWakeupCallbackEventType() const { CoreTiming::EventType* KernelCore::ThreadWakeupCallbackEventType() const {
return impl->thread_wakeup_event_type; return impl->thread_wakeup_event_type;
} }
CoreTiming::EventType* KernelCore::TimerCallbackEventType() const {
return impl->timer_callback_event_type;
}
Kernel::HandleTable& KernelCore::ThreadWakeupCallbackHandleTable() { Kernel::HandleTable& KernelCore::ThreadWakeupCallbackHandleTable() {
return impl->thread_wakeup_callback_handle_table; return impl->thread_wakeup_callback_handle_table;
} }

@ -22,7 +22,6 @@ class HandleTable;
class Process; class Process;
class ResourceLimit; class ResourceLimit;
class Thread; class Thread;
class Timer;
/// Represents a single instance of the kernel. /// Represents a single instance of the kernel.
class KernelCore { class KernelCore {
@ -51,9 +50,6 @@ public:
/// Retrieves a shared pointer to a Thread instance within the thread wakeup handle table. /// Retrieves a shared pointer to a Thread instance within the thread wakeup handle table.
SharedPtr<Thread> RetrieveThreadFromWakeupCallbackHandleTable(Handle handle) const; SharedPtr<Thread> RetrieveThreadFromWakeupCallbackHandleTable(Handle handle) const;
/// Retrieves a shared pointer to a Timer instance within the timer callback handle table.
SharedPtr<Timer> RetrieveTimerFromCallbackHandleTable(Handle handle) const;
/// Adds the given shared pointer to an internal list of active processes. /// Adds the given shared pointer to an internal list of active processes.
void AppendNewProcess(SharedPtr<Process> process); void AppendNewProcess(SharedPtr<Process> process);
@ -82,7 +78,6 @@ private:
friend class Object; friend class Object;
friend class Process; friend class Process;
friend class Thread; friend class Thread;
friend class Timer;
/// Creates a new object ID, incrementing the internal object ID counter. /// Creates a new object ID, incrementing the internal object ID counter.
u32 CreateNewObjectID(); u32 CreateNewObjectID();
@ -93,15 +88,9 @@ private:
/// Creates a new thread ID, incrementing the internal thread ID counter. /// Creates a new thread ID, incrementing the internal thread ID counter.
u64 CreateNewThreadID(); u64 CreateNewThreadID();
/// Creates a timer callback handle for the given timer.
ResultVal<Handle> CreateTimerCallbackHandle(const SharedPtr<Timer>& timer);
/// Retrieves the event type used for thread wakeup callbacks. /// Retrieves the event type used for thread wakeup callbacks.
CoreTiming::EventType* ThreadWakeupCallbackEventType() const; CoreTiming::EventType* ThreadWakeupCallbackEventType() const;
/// Retrieves the event type used for timer callbacks.
CoreTiming::EventType* TimerCallbackEventType() const;
/// Provides a reference to the thread wakeup callback handle table. /// Provides a reference to the thread wakeup callback handle table.
Kernel::HandleTable& ThreadWakeupCallbackHandleTable(); Kernel::HandleTable& ThreadWakeupCallbackHandleTable();

@ -16,7 +16,6 @@ bool Object::IsWaitable() const {
case HandleType::ReadableEvent: case HandleType::ReadableEvent:
case HandleType::Thread: case HandleType::Thread:
case HandleType::Process: case HandleType::Process:
case HandleType::Timer:
case HandleType::ServerPort: case HandleType::ServerPort:
case HandleType::ServerSession: case HandleType::ServerSession:
return true; return true;

@ -25,7 +25,6 @@ enum class HandleType : u32 {
Thread, Thread,
Process, Process,
AddressArbiter, AddressArbiter,
Timer,
ResourceLimit, ResourceLimit,
ClientPort, ClientPort,
ServerPort, ServerPort,

@ -1,84 +0,0 @@
// Copyright 2015 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/assert.h"
#include "common/logging/log.h"
#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/object.h"
#include "core/hle/kernel/thread.h"
#include "core/hle/kernel/timer.h"
namespace Kernel {
Timer::Timer(KernelCore& kernel) : WaitObject{kernel} {}
Timer::~Timer() = default;
SharedPtr<Timer> Timer::Create(KernelCore& kernel, ResetType reset_type, std::string name) {
SharedPtr<Timer> timer(new Timer(kernel));
timer->reset_type = reset_type;
timer->signaled = false;
timer->name = std::move(name);
timer->initial_delay = 0;
timer->interval_delay = 0;
timer->callback_handle = kernel.CreateTimerCallbackHandle(timer).Unwrap();
return timer;
}
bool Timer::ShouldWait(Thread* thread) const {
return !signaled;
}
void Timer::Acquire(Thread* thread) {
ASSERT_MSG(!ShouldWait(thread), "object unavailable!");
if (reset_type == ResetType::OneShot)
signaled = false;
}
void Timer::Set(s64 initial, s64 interval) {
// Ensure we get rid of any previous scheduled event
Cancel();
initial_delay = initial;
interval_delay = interval;
if (initial == 0) {
// Immediately invoke the callback
Signal(0);
} else {
CoreTiming::ScheduleEvent(CoreTiming::nsToCycles(initial), kernel.TimerCallbackEventType(),
callback_handle);
}
}
void Timer::Cancel() {
CoreTiming::UnscheduleEvent(kernel.TimerCallbackEventType(), callback_handle);
}
void Timer::Clear() {
signaled = false;
}
void Timer::Signal(int cycles_late) {
LOG_TRACE(Kernel, "Timer {} fired", GetObjectId());
signaled = true;
// Resume all waiting threads
WakeupAllWaitingThreads();
if (interval_delay != 0) {
// Reschedule the timer with the interval delay
CoreTiming::ScheduleEvent(CoreTiming::nsToCycles(interval_delay) - cycles_late,
kernel.TimerCallbackEventType(), callback_handle);
}
}
} // namespace Kernel

@ -1,88 +0,0 @@
// Copyright 2015 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "common/common_types.h"
#include "core/hle/kernel/object.h"
#include "core/hle/kernel/wait_object.h"
namespace Kernel {
class KernelCore;
class Timer final : public WaitObject {
public:
/**
* Creates a timer
* @param kernel The kernel instance to create the timer callback handle for.
* @param reset_type ResetType describing how to create the timer
* @param name Optional name of timer
* @return The created Timer
*/
static SharedPtr<Timer> Create(KernelCore& kernel, ResetType reset_type,
std::string name = "Unknown");
std::string GetTypeName() const override {
return "Timer";
}
std::string GetName() const override {
return name;
}
static const HandleType HANDLE_TYPE = HandleType::Timer;
HandleType GetHandleType() const override {
return HANDLE_TYPE;
}
ResetType GetResetType() const {
return reset_type;
}
u64 GetInitialDelay() const {
return initial_delay;
}
u64 GetIntervalDelay() const {
return interval_delay;
}
bool ShouldWait(Thread* thread) const override;
void Acquire(Thread* thread) override;
/**
* Starts the timer, with the specified initial delay and interval.
* @param initial Delay until the timer is first fired
* @param interval Delay until the timer is fired after the first time
*/
void Set(s64 initial, s64 interval);
void Cancel();
void Clear();
/**
* Signals the timer, waking up any waiting threads and rescheduling it
* for the next interval.
* This method should not be called from outside the timer callback handler,
* lest multiple callback events get scheduled.
*/
void Signal(int cycles_late);
private:
explicit Timer(KernelCore& kernel);
~Timer() override;
ResetType reset_type; ///< The ResetType of this timer
u64 initial_delay; ///< The delay until the timer fires for the first time
u64 interval_delay; ///< The delay until the timer fires after the first time
bool signaled; ///< Whether the timer has been signaled or not
std::string name; ///< Name of timer (optional)
/// Handle used as userdata to reference this object when inserting into the CoreTiming queue.
Handle callback_handle;
};
} // namespace Kernel

@ -13,7 +13,6 @@
#include "core/hle/kernel/readable_event.h" #include "core/hle/kernel/readable_event.h"
#include "core/hle/kernel/scheduler.h" #include "core/hle/kernel/scheduler.h"
#include "core/hle/kernel/thread.h" #include "core/hle/kernel/thread.h"
#include "core/hle/kernel/timer.h"
#include "core/hle/kernel/wait_object.h" #include "core/hle/kernel/wait_object.h"
#include "core/memory.h" #include "core/memory.h"
@ -155,8 +154,6 @@ std::unique_ptr<WaitTreeWaitObject> WaitTreeWaitObject::make(const Kernel::WaitO
switch (object.GetHandleType()) { switch (object.GetHandleType()) {
case Kernel::HandleType::ReadableEvent: case Kernel::HandleType::ReadableEvent:
return std::make_unique<WaitTreeEvent>(static_cast<const Kernel::ReadableEvent&>(object)); return std::make_unique<WaitTreeEvent>(static_cast<const Kernel::ReadableEvent&>(object));
case Kernel::HandleType::Timer:
return std::make_unique<WaitTreeTimer>(static_cast<const Kernel::Timer&>(object));
case Kernel::HandleType::Thread: case Kernel::HandleType::Thread:
return std::make_unique<WaitTreeThread>(static_cast<const Kernel::Thread&>(object)); return std::make_unique<WaitTreeThread>(static_cast<const Kernel::Thread&>(object));
default: default:
@ -348,23 +345,6 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeEvent::GetChildren() const {
return list; return list;
} }
WaitTreeTimer::WaitTreeTimer(const Kernel::Timer& object) : WaitTreeWaitObject(object) {}
WaitTreeTimer::~WaitTreeTimer() = default;
std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeTimer::GetChildren() const {
std::vector<std::unique_ptr<WaitTreeItem>> list(WaitTreeWaitObject::GetChildren());
const auto& timer = static_cast<const Kernel::Timer&>(object);
list.push_back(std::make_unique<WaitTreeText>(
tr("reset type = %1").arg(GetResetTypeQString(timer.GetResetType()))));
list.push_back(
std::make_unique<WaitTreeText>(tr("initial delay = %1").arg(timer.GetInitialDelay())));
list.push_back(
std::make_unique<WaitTreeText>(tr("interval delay = %1").arg(timer.GetIntervalDelay())));
return list;
}
WaitTreeThreadList::WaitTreeThreadList(const std::vector<Kernel::SharedPtr<Kernel::Thread>>& list) WaitTreeThreadList::WaitTreeThreadList(const std::vector<Kernel::SharedPtr<Kernel::Thread>>& list)
: thread_list(list) {} : thread_list(list) {}
WaitTreeThreadList::~WaitTreeThreadList() = default; WaitTreeThreadList::~WaitTreeThreadList() = default;

@ -20,7 +20,6 @@ namespace Kernel {
class ReadableEvent; class ReadableEvent;
class WaitObject; class WaitObject;
class Thread; class Thread;
class Timer;
} // namespace Kernel } // namespace Kernel
class WaitTreeThread; class WaitTreeThread;
@ -150,15 +149,6 @@ public:
std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
}; };
class WaitTreeTimer : public WaitTreeWaitObject {
Q_OBJECT
public:
explicit WaitTreeTimer(const Kernel::Timer& object);
~WaitTreeTimer() override;
std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
};
class WaitTreeThreadList : public WaitTreeExpandableItem { class WaitTreeThreadList : public WaitTreeExpandableItem {
Q_OBJECT Q_OBJECT
public: public: