From fc017ead67547d698dee18eb38b46e3bd882fc79 Mon Sep 17 00:00:00 2001 From: Adam Heinermann Date: Wed, 17 Nov 2021 15:00:55 -0800 Subject: Fix crash on exit due to static scoped dummy threads --- src/core/hle/kernel/kernel.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'src/core/hle/kernel/kernel.cpp') diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index e42a6d36fd..45e86a6774 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -300,15 +300,16 @@ struct KernelCore::Impl { // Gets the dummy KThread for the caller, allocating a new one if this is the first time KThread* GetHostDummyThread() { auto make_thread = [this]() { - std::unique_ptr thread = std::make_unique(system.Kernel()); + std::lock_guard lk(dummy_thread_lock); + auto& thread = dummy_threads.emplace_back(std::make_unique(system.Kernel())); KAutoObject::Create(thread.get()); ASSERT(KThread::InitializeDummyThread(thread.get()).IsSuccess()); thread->SetName(fmt::format("DummyThread:{}", GetHostThreadId())); - return thread; + return thread.get(); }; - thread_local auto thread = make_thread(); - return thread.get(); + thread_local KThread* saved_thread = make_thread(); + return saved_thread; } /// Registers a CPU core thread by allocating a host thread ID for it @@ -695,6 +696,12 @@ struct KernelCore::Impl { return port; } + std::mutex server_ports_lock; + std::mutex server_sessions_lock; + std::mutex registered_objects_lock; + std::mutex registered_in_use_objects_lock; + std::mutex dummy_thread_lock; + std::atomic next_object_id{0}; std::atomic next_kernel_process_id{KProcess::InitialKIPIDMin}; std::atomic next_user_process_id{KProcess::ProcessIDMin}; @@ -725,10 +732,6 @@ struct KernelCore::Impl { std::unordered_set server_sessions; std::unordered_set registered_objects; std::unordered_set registered_in_use_objects; - std::mutex server_ports_lock; - std::mutex server_sessions_lock; - std::mutex registered_objects_lock; - std::mutex registered_in_use_objects_lock; std::unique_ptr exclusive_monitor; std::vector cores; @@ -753,6 +756,9 @@ struct KernelCore::Impl { std::array interrupts{}; std::array, Core::Hardware::NUM_CPU_CORES> schedulers{}; + // Specifically tracked to be automatically destroyed with kernel + std::vector> dummy_threads; + bool is_multicore{}; bool is_phantom_mode_for_singlecore{}; u32 single_core_thread_id{}; -- cgit v1.2.3 From cae0bef7ec1510779cdb400cb2af36b1577c831d Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 6 Aug 2021 22:45:18 -0700 Subject: core: hle: kernel: Reflect non-emulated threads as core 3. --- src/core/core.cpp | 6 ------ src/core/core.h | 3 --- src/core/hle/kernel/k_address_arbiter.cpp | 4 ++-- src/core/hle/kernel/k_condition_variable.cpp | 2 +- src/core/hle/kernel/kernel.cpp | 8 ++++++++ src/core/hle/kernel/kernel.h | 3 +++ src/core/hle/kernel/svc.cpp | 5 +++-- 7 files changed, 17 insertions(+), 14 deletions(-) (limited to 'src/core/hle/kernel/kernel.cpp') diff --git a/src/core/core.cpp b/src/core/core.cpp index 473ab9f817..aa96f709b5 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -521,12 +521,6 @@ const ARM_Interface& System::CurrentArmInterface() const { return impl->kernel.CurrentPhysicalCore().ArmInterface(); } -std::size_t System::CurrentCoreIndex() const { - std::size_t core = impl->kernel.GetCurrentHostThreadID(); - ASSERT(core < Core::Hardware::NUM_CPU_CORES); - return core; -} - Kernel::PhysicalCore& System::CurrentPhysicalCore() { return impl->kernel.CurrentPhysicalCore(); } diff --git a/src/core/core.h b/src/core/core.h index 645e5c241c..52ff90359a 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -208,9 +208,6 @@ public: /// Gets an ARM interface to the CPU core that is currently running [[nodiscard]] const ARM_Interface& CurrentArmInterface() const; - /// Gets the index of the currently running CPU core - [[nodiscard]] std::size_t CurrentCoreIndex() const; - /// Gets the physical core for the CPU core that is currently running [[nodiscard]] Kernel::PhysicalCore& CurrentPhysicalCore(); diff --git a/src/core/hle/kernel/k_address_arbiter.cpp b/src/core/hle/kernel/k_address_arbiter.cpp index 1b429bc1e3..6771ef6213 100644 --- a/src/core/hle/kernel/k_address_arbiter.cpp +++ b/src/core/hle/kernel/k_address_arbiter.cpp @@ -28,7 +28,7 @@ bool ReadFromUser(Core::System& system, s32* out, VAddr address) { bool DecrementIfLessThan(Core::System& system, s32* out, VAddr address, s32 value) { auto& monitor = system.Monitor(); - const auto current_core = system.CurrentCoreIndex(); + const auto current_core = system.Kernel().CurrentPhysicalCoreIndex(); // TODO(bunnei): We should disable interrupts here via KScopedInterruptDisable. // TODO(bunnei): We should call CanAccessAtomic(..) here. @@ -58,7 +58,7 @@ bool DecrementIfLessThan(Core::System& system, s32* out, VAddr address, s32 valu bool UpdateIfEqual(Core::System& system, s32* out, VAddr address, s32 value, s32 new_value) { auto& monitor = system.Monitor(); - const auto current_core = system.CurrentCoreIndex(); + const auto current_core = system.Kernel().CurrentPhysicalCoreIndex(); // TODO(bunnei): We should disable interrupts here via KScopedInterruptDisable. // TODO(bunnei): We should call CanAccessAtomic(..) here. diff --git a/src/core/hle/kernel/k_condition_variable.cpp b/src/core/hle/kernel/k_condition_variable.cpp index 7fa9b8cc3e..ed6f328fc2 100644 --- a/src/core/hle/kernel/k_condition_variable.cpp +++ b/src/core/hle/kernel/k_condition_variable.cpp @@ -33,7 +33,7 @@ bool WriteToUser(Core::System& system, VAddr address, const u32* p) { bool UpdateLockAtomic(Core::System& system, u32* out, VAddr address, u32 if_zero, u32 new_orr_mask) { auto& monitor = system.Monitor(); - const auto current_core = system.CurrentCoreIndex(); + const auto current_core = system.Kernel().CurrentPhysicalCoreIndex(); // Load the value from the address. const auto expected = monitor.ExclusiveRead32(current_core, address); diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 45e86a6774..04926a2916 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -845,6 +845,14 @@ const Kernel::PhysicalCore& KernelCore::PhysicalCore(std::size_t id) const { return impl->cores[id]; } +size_t KernelCore::CurrentPhysicalCoreIndex() const { + const u32 core_id = impl->GetCurrentHostThreadID(); + if (core_id >= Core::Hardware::NUM_CPU_CORES) { + return Core::Hardware::NUM_CPU_CORES - 1; + } + return core_id; +} + Kernel::PhysicalCore& KernelCore::CurrentPhysicalCore() { u32 core_id = impl->GetCurrentHostThreadID(); ASSERT(core_id < Core::Hardware::NUM_CPU_CORES); diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index d2ceae9505..3499f8b903 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -148,6 +148,9 @@ public: /// Gets the an instance of the respective physical CPU core. const Kernel::PhysicalCore& PhysicalCore(std::size_t id) const; + /// Gets the current physical core index for the running host thread. + std::size_t CurrentPhysicalCoreIndex() const; + /// Gets the sole instance of the Scheduler at the current running core. Kernel::KScheduler* CurrentScheduler(); diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index f0cd8471e8..e5e879eb5d 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -873,7 +873,7 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle const u64 thread_ticks = current_thread->GetCpuTime(); out_ticks = thread_ticks + (core_timing.GetCPUTicks() - prev_ctx_ticks); - } else if (same_thread && info_sub_id == system.CurrentCoreIndex()) { + } else if (same_thread && info_sub_id == system.Kernel().CurrentPhysicalCoreIndex()) { out_ticks = core_timing.GetCPUTicks() - prev_ctx_ticks; } @@ -887,7 +887,8 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle return ResultInvalidHandle; } - if (info_sub_id != 0xFFFFFFFFFFFFFFFF && info_sub_id != system.CurrentCoreIndex()) { + if (info_sub_id != 0xFFFFFFFFFFFFFFFF && + info_sub_id != system.Kernel().CurrentPhysicalCoreIndex()) { LOG_ERROR(Kernel_SVC, "Core is not the current core, got {}", info_sub_id); return ResultInvalidCombination; } -- cgit v1.2.3 From fa26f905c81b0da4ce39843cc4824d51bb08db71 Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 6 Aug 2021 22:58:46 -0700 Subject: core: hle: kernel: Ensure idle threads are closed before destroying scheduler. --- src/core/hle/kernel/k_scheduler.cpp | 6 +++++- src/core/hle/kernel/k_scheduler.h | 2 ++ src/core/hle/kernel/kernel.cpp | 38 +++++++++++++++---------------------- 3 files changed, 22 insertions(+), 24 deletions(-) (limited to 'src/core/hle/kernel/kernel.cpp') diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp index 6a7d80d032..4bae69f716 100644 --- a/src/core/hle/kernel/k_scheduler.cpp +++ b/src/core/hle/kernel/k_scheduler.cpp @@ -617,13 +617,17 @@ KScheduler::KScheduler(Core::System& system_, s32 core_id_) : system{system_}, c state.highest_priority_thread = nullptr; } -KScheduler::~KScheduler() { +void KScheduler::Finalize() { if (idle_thread) { idle_thread->Close(); idle_thread = nullptr; } } +KScheduler::~KScheduler() { + ASSERT(!idle_thread); +} + KThread* KScheduler::GetCurrentThread() const { if (auto result = current_thread.load(); result) { return result; diff --git a/src/core/hle/kernel/k_scheduler.h b/src/core/hle/kernel/k_scheduler.h index 7df2884383..82fcd99e7b 100644 --- a/src/core/hle/kernel/k_scheduler.h +++ b/src/core/hle/kernel/k_scheduler.h @@ -33,6 +33,8 @@ public: explicit KScheduler(Core::System& system_, s32 core_id_); ~KScheduler(); + void Finalize(); + /// Reschedules to the next available thread (call after current thread is suspended) void RescheduleCurrentCore(); diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 04926a2916..275fee0d86 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -83,8 +83,9 @@ struct KernelCore::Impl { } void InitializeCores() { - for (auto& core : cores) { - core.Initialize(current_process->Is64BitProcess()); + for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { + cores[core_id].Initialize(current_process->Is64BitProcess()); + system.Memory().SetCurrentPageTable(*current_process, core_id); } } @@ -123,15 +124,6 @@ struct KernelCore::Impl { next_user_process_id = KProcess::ProcessIDMin; next_thread_id = 1; - for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { - if (suspend_threads[core_id]) { - suspend_threads[core_id]->Close(); - suspend_threads[core_id] = nullptr; - } - - schedulers[core_id].reset(); - } - cores.clear(); global_handle_table->Finalize(); @@ -159,6 +151,16 @@ struct KernelCore::Impl { CleanupObject(time_shared_mem); CleanupObject(system_resource_limit); + for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { + if (suspend_threads[core_id]) { + suspend_threads[core_id]->Close(); + suspend_threads[core_id] = nullptr; + } + + schedulers[core_id]->Finalize(); + schedulers[core_id].reset(); + } + // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others next_host_thread_id = Core::Hardware::NUM_CPU_CORES; @@ -267,14 +269,6 @@ struct KernelCore::Impl { void MakeCurrentProcess(KProcess* process) { current_process = process; - if (process == nullptr) { - return; - } - - const u32 core_id = GetCurrentHostThreadID(); - if (core_id < Core::Hardware::NUM_CPU_CORES) { - system.Memory().SetCurrentPageTable(*process, core_id); - } } static inline thread_local u32 host_thread_id = UINT32_MAX; @@ -1079,13 +1073,11 @@ void KernelCore::ExceptionalExit() { } void KernelCore::EnterSVCProfile() { - std::size_t core = impl->GetCurrentHostThreadID(); - impl->svc_ticks[core] = MicroProfileEnter(MICROPROFILE_TOKEN(Kernel_SVC)); + impl->svc_ticks[CurrentPhysicalCoreIndex()] = MicroProfileEnter(MICROPROFILE_TOKEN(Kernel_SVC)); } void KernelCore::ExitSVCProfile() { - std::size_t core = impl->GetCurrentHostThreadID(); - MicroProfileLeave(MICROPROFILE_TOKEN(Kernel_SVC), impl->svc_ticks[core]); + MicroProfileLeave(MICROPROFILE_TOKEN(Kernel_SVC), impl->svc_ticks[CurrentPhysicalCoreIndex()]); } std::weak_ptr KernelCore::CreateServiceThread(const std::string& name) { -- cgit v1.2.3 From 3a83c9c027ed386f4242d5e51442551aa163f2a8 Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 6 Aug 2021 23:20:07 -0700 Subject: core: hle: kernel: Use CurrentPhysicalCoreIndex as appropriate. --- src/core/hle/kernel/kernel.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'src/core/hle/kernel/kernel.cpp') diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 275fee0d86..2884886442 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -848,15 +848,11 @@ size_t KernelCore::CurrentPhysicalCoreIndex() const { } Kernel::PhysicalCore& KernelCore::CurrentPhysicalCore() { - u32 core_id = impl->GetCurrentHostThreadID(); - ASSERT(core_id < Core::Hardware::NUM_CPU_CORES); - return impl->cores[core_id]; + return impl->cores[CurrentPhysicalCoreIndex()]; } const Kernel::PhysicalCore& KernelCore::CurrentPhysicalCore() const { - u32 core_id = impl->GetCurrentHostThreadID(); - ASSERT(core_id < Core::Hardware::NUM_CPU_CORES); - return impl->cores[core_id]; + return impl->cores[CurrentPhysicalCoreIndex()]; } Kernel::KScheduler* KernelCore::CurrentScheduler() { -- cgit v1.2.3 From 51a7f04b815ad3634fec978896e71fce906ba2a1 Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 6 Aug 2021 23:43:26 -0700 Subject: core: hle: kernel: DisableDispatch on suspend threads. --- src/core/hle/kernel/kernel.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/core/hle/kernel/kernel.cpp') diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 2884886442..cf155ff66e 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -1055,6 +1055,9 @@ void KernelCore::Suspend(bool in_suspention) { impl->suspend_threads[core_id]->SetState(state); impl->suspend_threads[core_id]->SetWaitReasonForDebugging( ThreadWaitReasonForDebugging::Suspended); + if (!should_suspend) { + impl->suspend_threads[core_id]->DisableDispatch(); + } } } } -- cgit v1.2.3 From 58da4d5a6e645743936f70d136931829ab755d5e Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 25 Nov 2021 20:46:17 -0800 Subject: hle: kernel: Add a flag for indicating that the kernel is currently shutting down. --- src/core/hle/kernel/k_scheduler.cpp | 10 ++++++++++ src/core/hle/kernel/k_scheduler_lock.h | 10 ++++++++++ src/core/hle/kernel/k_thread.cpp | 5 +++++ src/core/hle/kernel/k_thread.h | 4 ++++ src/core/hle/kernel/kernel.cpp | 18 ++++++++++++++++++ src/core/hle/kernel/kernel.h | 2 ++ 6 files changed, 49 insertions(+) (limited to 'src/core/hle/kernel/kernel.cpp') diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp index 6ddbae52cd..5423b187ed 100644 --- a/src/core/hle/kernel/k_scheduler.cpp +++ b/src/core/hle/kernel/k_scheduler.cpp @@ -376,11 +376,21 @@ void KScheduler::ClearSchedulerUpdateNeeded(KernelCore& kernel) { } void KScheduler::DisableScheduling(KernelCore& kernel) { + // If we are shutting down the kernel, none of this is relevant anymore. + if (kernel.IsShuttingDown()) { + return; + } + ASSERT(GetCurrentThreadPointer(kernel)->GetDisableDispatchCount() >= 0); GetCurrentThreadPointer(kernel)->DisableDispatch(); } void KScheduler::EnableScheduling(KernelCore& kernel, u64 cores_needing_scheduling) { + // If we are shutting down the kernel, none of this is relevant anymore. + if (kernel.IsShuttingDown()) { + return; + } + ASSERT(GetCurrentThreadPointer(kernel)->GetDisableDispatchCount() >= 1); if (GetCurrentThreadPointer(kernel)->GetDisableDispatchCount() > 1) { diff --git a/src/core/hle/kernel/k_scheduler_lock.h b/src/core/hle/kernel/k_scheduler_lock.h index c571f29921..93c47f1b19 100644 --- a/src/core/hle/kernel/k_scheduler_lock.h +++ b/src/core/hle/kernel/k_scheduler_lock.h @@ -23,6 +23,11 @@ public: } void Lock() { + // If we are shutting down the kernel, none of this is relevant anymore. + if (kernel.IsShuttingDown()) { + return; + } + if (IsLockedByCurrentThread()) { // If we already own the lock, we can just increment the count. ASSERT(lock_count > 0); @@ -43,6 +48,11 @@ public: } void Unlock() { + // If we are shutting down the kernel, none of this is relevant anymore. + if (kernel.IsShuttingDown()) { + return; + } + ASSERT(IsLockedByCurrentThread()); ASSERT(lock_count > 0); diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index 813b92ea43..f69978cafb 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp @@ -1089,6 +1089,11 @@ s32 GetCurrentCoreId(KernelCore& kernel) { } KScopedDisableDispatch::~KScopedDisableDispatch() { + // If we are shutting down the kernel, none of this is relevant anymore. + if (kernel.IsShuttingDown()) { + return; + } + if (GetCurrentThread(kernel).GetDisableDispatchCount() <= 1) { auto scheduler = kernel.CurrentScheduler(); diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h index 1cde71e895..be1bc59aeb 100644 --- a/src/core/hle/kernel/k_thread.h +++ b/src/core/hle/kernel/k_thread.h @@ -794,6 +794,10 @@ public: class KScopedDisableDispatch { public: [[nodiscard]] explicit KScopedDisableDispatch(KernelCore& kernel_) : kernel{kernel_} { + // If we are shutting down the kernel, none of this is relevant anymore. + if (kernel.IsShuttingDown()) { + return; + } GetCurrentThread(kernel).DisableDispatch(); } diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index cf155ff66e..1a47d4716a 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -14,6 +14,7 @@ #include "common/assert.h" #include "common/logging/log.h" #include "common/microprofile.h" +#include "common/scope_exit.h" #include "common/thread.h" #include "common/thread_worker.h" #include "core/arm/arm_interface.h" @@ -90,6 +91,9 @@ struct KernelCore::Impl { } void Shutdown() { + is_shutting_down.store(true, std::memory_order_relaxed); + SCOPE_EXIT({ is_shutting_down.store(false, std::memory_order_relaxed); }); + process_list.clear(); // Close all open server ports. @@ -338,7 +342,16 @@ struct KernelCore::Impl { is_phantom_mode_for_singlecore = value; } + bool IsShuttingDown() const { + return is_shutting_down.load(std::memory_order_relaxed); + } + KThread* GetCurrentEmuThread() { + // If we are shutting down the kernel, none of this is relevant anymore. + if (IsShuttingDown()) { + return {}; + } + const auto thread_id = GetCurrentHostThreadID(); if (thread_id >= Core::Hardware::NUM_CPU_CORES) { return GetHostDummyThread(); @@ -754,6 +767,7 @@ struct KernelCore::Impl { std::vector> dummy_threads; bool is_multicore{}; + std::atomic_bool is_shutting_down{}; bool is_phantom_mode_for_singlecore{}; u32 single_core_thread_id{}; @@ -1066,6 +1080,10 @@ bool KernelCore::IsMulticore() const { return impl->is_multicore; } +bool KernelCore::IsShuttingDown() const { + return impl->IsShuttingDown(); +} + void KernelCore::ExceptionalExit() { exception_exited = true; Suspend(true); diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 3499f8b903..eacf9dc611 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -274,6 +274,8 @@ public: bool IsMulticore() const; + bool IsShuttingDown() const; + void EnterSVCProfile(); void ExitSVCProfile(); -- cgit v1.2.3 From 8a38790bd380606001783e61b0f36f88a30a7d01 Mon Sep 17 00:00:00 2001 From: FernandoS27 Date: Fri, 26 Nov 2021 18:16:54 +0100 Subject: hle: kernel: fix timing on thread preemption --- src/core/hle/kernel/kernel.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/core/hle/kernel/kernel.cpp') diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 1a47d4716a..2e4e4cb1cc 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -251,13 +251,11 @@ struct KernelCore::Impl { KScopedSchedulerLock lock(kernel); global_scheduler_context->PreemptThreads(); } - const auto time_interval = std::chrono::nanoseconds{ - Core::Timing::msToCycles(std::chrono::milliseconds(10))}; + const auto time_interval = std::chrono::nanoseconds{std::chrono::milliseconds(10)}; system.CoreTiming().ScheduleEvent(time_interval, preemption_event); }); - const auto time_interval = - std::chrono::nanoseconds{Core::Timing::msToCycles(std::chrono::milliseconds(10))}; + const auto time_interval = std::chrono::nanoseconds{std::chrono::milliseconds(10)}; system.CoreTiming().ScheduleEvent(time_interval, preemption_event); } -- cgit v1.2.3