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/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:
|
||||||
|
|
Loading…
Reference in New Issue