diff options
author | Gunnar Beutner <gbeutner@serenityos.org> | 2021-05-20 02:06:57 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-05-20 09:09:10 +0200 |
commit | 8495d6aecaa338ce17172c762578617aefc60656 (patch) | |
tree | 110a4244bb7618e5590f8edc98b9f4913963f5dc /Kernel/Arch/x86/CPU.h | |
parent | cac7a8ced9437a3187ab8d63dad42219c3f5e8b0 (diff) | |
download | serenity-8495d6aecaa338ce17172c762578617aefc60656.zip |
Kernel: Use the Function class for smp_broadcast()/smp_unicast()
This avoids allocations for smp_broadcast() and smp_unicast() by
using the Function class.
Diffstat (limited to 'Kernel/Arch/x86/CPU.h')
-rw-r--r-- | Kernel/Arch/x86/CPU.h | 58 |
1 files changed, 16 insertions, 42 deletions
diff --git a/Kernel/Arch/x86/CPU.h b/Kernel/Arch/x86/CPU.h index 4929ccba62..d17e1ffb23 100644 --- a/Kernel/Arch/x86/CPU.h +++ b/Kernel/Arch/x86/CPU.h @@ -574,23 +574,17 @@ struct MemoryManagerData; struct ProcessorMessageEntry; struct ProcessorMessage { + using CallbackFunction = Function<void()>; + enum Type { FlushTlb, Callback, - CallbackWithData }; Type type; volatile u32 refs; // atomic union { ProcessorMessage* next; // only valid while in the pool - struct { - void (*handler)(); - } callback; - struct { - void* data; - void (*handler)(void*); - void (*free)(void*); - } callback_with_data; + alignas(CallbackFunction) u8 callback_storage[sizeof(CallbackFunction)]; struct { const PageDirectory* page_directory; u8* ptr; @@ -601,6 +595,17 @@ struct ProcessorMessage { volatile bool async; ProcessorMessageEntry* per_proc_entries; + + CallbackFunction& callback_value() + { + return *bit_cast<CallbackFunction*>(&callback_storage); + } + + void invoke_callback() + { + VERIFY(type == Type::Callback); + callback_value()(); + } }; struct ProcessorMessageEntry { @@ -942,39 +947,8 @@ public: static void smp_enable(); bool smp_process_pending_messages(); - template<typename Callback> - static void smp_broadcast(Callback callback, bool async) - { - auto* data = new Callback(move(callback)); - smp_broadcast( - [](void* data) { - (*reinterpret_cast<Callback*>(data))(); - }, - data, - [](void* data) { - delete reinterpret_cast<Callback*>(data); - }, - async); - } - static void smp_broadcast(void (*callback)(), bool async); - static void smp_broadcast(void (*callback)(void*), void* data, void (*free_data)(void*), bool async); - template<typename Callback> - static void smp_unicast(u32 cpu, Callback callback, bool async) - { - auto* data = new Callback(move(callback)); - smp_unicast( - cpu, - [](void* data) { - (*reinterpret_cast<Callback*>(data))(); - }, - data, - [](void* data) { - delete reinterpret_cast<Callback*>(data); - }, - async); - } - static void smp_unicast(u32 cpu, void (*callback)(), bool async); - static void smp_unicast(u32 cpu, void (*callback)(void*), void* data, void (*free_data)(void*), bool async); + static void smp_broadcast(Function<void()>, bool async); + static void smp_unicast(u32 cpu, Function<void()>, bool async); static void smp_broadcast_flush_tlb(const PageDirectory*, VirtualAddress, size_t); static u32 smp_wake_n_idle_processors(u32 wake_count); |