From 46215a8183d1a2b4d17c9501f6a9d5db484d00bb Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 8 Aug 2021 15:27:04 +0200 Subject: [PATCH] Kernel: Add Processor::pause() and use it to give the CPU a rest On x86, the "pause" instruction is a "spin loop hint". --- Kernel/Arch/x86/Processor.h | 7 ++++++- Kernel/Arch/x86/common/Processor.cpp | 6 +++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Kernel/Arch/x86/Processor.h b/Kernel/Arch/x86/Processor.h index beaf4ec122..609801792a 100644 --- a/Kernel/Arch/x86/Processor.h +++ b/Kernel/Arch/x86/Processor.h @@ -197,10 +197,15 @@ public: return *g_total_processors.ptr(); } + ALWAYS_INLINE static void pause() + { + asm volatile("pause"); + } + ALWAYS_INLINE static void wait_check() { + Processor::pause(); Processor::current().smp_process_pending_messages(); - // TODO: pause } [[noreturn]] static void halt(); diff --git a/Kernel/Arch/x86/common/Processor.cpp b/Kernel/Arch/x86/common/Processor.cpp index a15cfb32a4..1c200c2890 100644 --- a/Kernel/Arch/x86/common/Processor.cpp +++ b/Kernel/Arch/x86/common/Processor.cpp @@ -682,7 +682,7 @@ ProcessorMessage& Processor::smp_get_from_pool() msg = s_message_pool.load(AK::MemoryOrder::memory_order_consume); if (!msg) { if (!Processor::current().smp_process_pending_messages()) { - // TODO: pause for a bit? + Processor::pause(); } continue; } @@ -898,7 +898,7 @@ void Processor::smp_broadcast_wait_sync(ProcessorMessage& msg) // If synchronous then we must cleanup and return the message back // to the pool. Otherwise, the last processor to complete it will return it while (msg.refs.load(AK::MemoryOrder::memory_order_consume) != 0) { - // TODO: pause for a bit? + Processor::pause(); // We need to process any messages that may have been sent to // us while we're waiting. This also checks if another processor @@ -928,7 +928,7 @@ void Processor::smp_unicast_message(u32 cpu, ProcessorMessage& msg, bool async) // If synchronous then we must cleanup and return the message back // to the pool. Otherwise, the last processor to complete it will return it while (msg.refs.load(AK::MemoryOrder::memory_order_consume) != 0) { - // TODO: pause for a bit? + Processor::pause(); // We need to process any messages that may have been sent to // us while we're waiting. This also checks if another processor