mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	Merge pull request #2078 from lioncash/timer
kernel: Remove the Timer class
This commit is contained in:
		
						commit
						11e7c1244c
					
				@ -140,8 +140,6 @@ add_library(core STATIC
 | 
			
		||||
    hle/kernel/svc_wrap.h
 | 
			
		||||
    hle/kernel/thread.cpp
 | 
			
		||||
    hle/kernel/thread.h
 | 
			
		||||
    hle/kernel/timer.cpp
 | 
			
		||||
    hle/kernel/timer.h
 | 
			
		||||
    hle/kernel/vm_manager.cpp
 | 
			
		||||
    hle/kernel/vm_manager.h
 | 
			
		||||
    hle/kernel/wait_object.cpp
 | 
			
		||||
 | 
			
		||||
@ -18,7 +18,6 @@
 | 
			
		||||
#include "core/hle/kernel/process.h"
 | 
			
		||||
#include "core/hle/kernel/resource_limit.h"
 | 
			
		||||
#include "core/hle/kernel/thread.h"
 | 
			
		||||
#include "core/hle/kernel/timer.h"
 | 
			
		||||
#include "core/hle/lock.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 {
 | 
			
		||||
    void Initialize(KernelCore& kernel) {
 | 
			
		||||
        Shutdown();
 | 
			
		||||
 | 
			
		||||
        InitializeSystemResourceLimit(kernel);
 | 
			
		||||
        InitializeThreads();
 | 
			
		||||
        InitializeTimers();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void Shutdown() {
 | 
			
		||||
@ -122,9 +106,6 @@ struct KernelCore::Impl {
 | 
			
		||||
        thread_wakeup_callback_handle_table.Clear();
 | 
			
		||||
        thread_wakeup_event_type = nullptr;
 | 
			
		||||
 | 
			
		||||
        timer_callback_handle_table.Clear();
 | 
			
		||||
        timer_callback_event_type = nullptr;
 | 
			
		||||
 | 
			
		||||
        named_ports.clear();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -146,11 +127,6 @@ struct KernelCore::Impl {
 | 
			
		||||
            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<u64> next_process_id{Process::ProcessIDMin};
 | 
			
		||||
    std::atomic<u64> next_thread_id{1};
 | 
			
		||||
@ -161,12 +137,6 @@ struct KernelCore::Impl {
 | 
			
		||||
 | 
			
		||||
    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;
 | 
			
		||||
    // 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.
 | 
			
		||||
@ -198,10 +168,6 @@ SharedPtr<Thread> KernelCore::RetrieveThreadFromWakeupCallbackHandleTable(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) {
 | 
			
		||||
    impl->process_list.push_back(std::move(process));
 | 
			
		||||
}
 | 
			
		||||
@ -247,18 +213,10 @@ u64 KernelCore::CreateNewProcessID() {
 | 
			
		||||
    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 {
 | 
			
		||||
    return impl->thread_wakeup_event_type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CoreTiming::EventType* KernelCore::TimerCallbackEventType() const {
 | 
			
		||||
    return impl->timer_callback_event_type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Kernel::HandleTable& KernelCore::ThreadWakeupCallbackHandleTable() {
 | 
			
		||||
    return impl->thread_wakeup_callback_handle_table;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -22,7 +22,6 @@ class HandleTable;
 | 
			
		||||
class Process;
 | 
			
		||||
class ResourceLimit;
 | 
			
		||||
class Thread;
 | 
			
		||||
class Timer;
 | 
			
		||||
 | 
			
		||||
/// Represents a single instance of the kernel.
 | 
			
		||||
class KernelCore {
 | 
			
		||||
@ -51,9 +50,6 @@ public:
 | 
			
		||||
    /// Retrieves a shared pointer to a Thread instance within the thread wakeup handle table.
 | 
			
		||||
    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.
 | 
			
		||||
    void AppendNewProcess(SharedPtr<Process> process);
 | 
			
		||||
 | 
			
		||||
@ -82,7 +78,6 @@ private:
 | 
			
		||||
    friend class Object;
 | 
			
		||||
    friend class Process;
 | 
			
		||||
    friend class Thread;
 | 
			
		||||
    friend class Timer;
 | 
			
		||||
 | 
			
		||||
    /// Creates a new object ID, incrementing the internal object ID counter.
 | 
			
		||||
    u32 CreateNewObjectID();
 | 
			
		||||
@ -93,15 +88,9 @@ private:
 | 
			
		||||
    /// Creates a new thread ID, incrementing the internal thread ID counter.
 | 
			
		||||
    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.
 | 
			
		||||
    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.
 | 
			
		||||
    Kernel::HandleTable& ThreadWakeupCallbackHandleTable();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -16,7 +16,6 @@ bool Object::IsWaitable() const {
 | 
			
		||||
    case HandleType::ReadableEvent:
 | 
			
		||||
    case HandleType::Thread:
 | 
			
		||||
    case HandleType::Process:
 | 
			
		||||
    case HandleType::Timer:
 | 
			
		||||
    case HandleType::ServerPort:
 | 
			
		||||
    case HandleType::ServerSession:
 | 
			
		||||
        return true;
 | 
			
		||||
 | 
			
		||||
@ -25,7 +25,6 @@ enum class HandleType : u32 {
 | 
			
		||||
    Thread,
 | 
			
		||||
    Process,
 | 
			
		||||
    AddressArbiter,
 | 
			
		||||
    Timer,
 | 
			
		||||
    ResourceLimit,
 | 
			
		||||
    ClientPort,
 | 
			
		||||
    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/scheduler.h"
 | 
			
		||||
#include "core/hle/kernel/thread.h"
 | 
			
		||||
#include "core/hle/kernel/timer.h"
 | 
			
		||||
#include "core/hle/kernel/wait_object.h"
 | 
			
		||||
#include "core/memory.h"
 | 
			
		||||
 | 
			
		||||
@ -155,8 +154,6 @@ std::unique_ptr<WaitTreeWaitObject> WaitTreeWaitObject::make(const Kernel::WaitO
 | 
			
		||||
    switch (object.GetHandleType()) {
 | 
			
		||||
    case Kernel::HandleType::ReadableEvent:
 | 
			
		||||
        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:
 | 
			
		||||
        return std::make_unique<WaitTreeThread>(static_cast<const Kernel::Thread&>(object));
 | 
			
		||||
    default:
 | 
			
		||||
@ -348,23 +345,6 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeEvent::GetChildren() const {
 | 
			
		||||
    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)
 | 
			
		||||
    : thread_list(list) {}
 | 
			
		||||
WaitTreeThreadList::~WaitTreeThreadList() = default;
 | 
			
		||||
 | 
			
		||||
@ -20,7 +20,6 @@ namespace Kernel {
 | 
			
		||||
class ReadableEvent;
 | 
			
		||||
class WaitObject;
 | 
			
		||||
class Thread;
 | 
			
		||||
class Timer;
 | 
			
		||||
} // namespace Kernel
 | 
			
		||||
 | 
			
		||||
class WaitTreeThread;
 | 
			
		||||
@ -150,15 +149,6 @@ public:
 | 
			
		||||
    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 {
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user