mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-17 08:17:30 +03:00
Kernel: Use the Function class for smp_broadcast()/smp_unicast()
This avoids allocations for smp_broadcast() and smp_unicast() by using the Function class.
This commit is contained in:
parent
cac7a8ced9
commit
8495d6aeca
Notes:
sideshowbarker
2024-07-18 17:43:19 +09:00
Author: https://github.com/gunnarbeutner Commit: https://github.com/SerenityOS/serenity/commit/8495d6aecaa Pull-request: https://github.com/SerenityOS/serenity/pull/7301 Reviewed-by: https://github.com/bgianfo ✅
@ -1980,9 +1980,8 @@ UNMAP_AFTER_INIT void Processor::smp_enable()
|
|||||||
void Processor::smp_cleanup_message(ProcessorMessage& msg)
|
void Processor::smp_cleanup_message(ProcessorMessage& msg)
|
||||||
{
|
{
|
||||||
switch (msg.type) {
|
switch (msg.type) {
|
||||||
case ProcessorMessage::CallbackWithData:
|
case ProcessorMessage::Callback:
|
||||||
if (msg.callback_with_data.free)
|
msg.callback_value().~Function();
|
||||||
msg.callback_with_data.free(msg.callback_with_data.data);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -2021,10 +2020,7 @@ bool Processor::smp_process_pending_messages()
|
|||||||
|
|
||||||
switch (msg->type) {
|
switch (msg->type) {
|
||||||
case ProcessorMessage::Callback:
|
case ProcessorMessage::Callback:
|
||||||
msg->callback.handler();
|
msg->invoke_callback();
|
||||||
break;
|
|
||||||
case ProcessorMessage::CallbackWithData:
|
|
||||||
msg->callback_with_data.handler(msg->callback_with_data.data);
|
|
||||||
break;
|
break;
|
||||||
case ProcessorMessage::FlushTlb:
|
case ProcessorMessage::FlushTlb:
|
||||||
if (is_user_address(VirtualAddress(msg->flush_tlb.ptr))) {
|
if (is_user_address(VirtualAddress(msg->flush_tlb.ptr))) {
|
||||||
@ -2119,25 +2115,12 @@ void Processor::smp_broadcast_wait_sync(ProcessorMessage& msg)
|
|||||||
smp_return_to_pool(msg);
|
smp_return_to_pool(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Processor::smp_broadcast(void (*callback)(void*), void* data, void (*free_data)(void*), bool async)
|
void Processor::smp_broadcast(Function<void()> callback, bool async)
|
||||||
{
|
{
|
||||||
auto& msg = smp_get_from_pool();
|
auto& msg = smp_get_from_pool();
|
||||||
msg.async = async;
|
msg.async = async;
|
||||||
msg.type = ProcessorMessage::CallbackWithData;
|
msg.type = ProcessorMessage::Callback;
|
||||||
msg.callback_with_data.handler = callback;
|
new (msg.callback_storage) ProcessorMessage::CallbackFunction(move(callback));
|
||||||
msg.callback_with_data.data = data;
|
|
||||||
msg.callback_with_data.free = free_data;
|
|
||||||
smp_broadcast_message(msg);
|
|
||||||
if (!async)
|
|
||||||
smp_broadcast_wait_sync(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Processor::smp_broadcast(void (*callback)(), bool async)
|
|
||||||
{
|
|
||||||
auto& msg = smp_get_from_pool();
|
|
||||||
msg.async = async;
|
|
||||||
msg.type = ProcessorMessage::CallbackWithData;
|
|
||||||
msg.callback.handler = callback;
|
|
||||||
smp_broadcast_message(msg);
|
smp_broadcast_message(msg);
|
||||||
if (!async)
|
if (!async)
|
||||||
smp_broadcast_wait_sync(msg);
|
smp_broadcast_wait_sync(msg);
|
||||||
@ -2174,21 +2157,11 @@ void Processor::smp_unicast_message(u32 cpu, ProcessorMessage& msg, bool async)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Processor::smp_unicast(u32 cpu, void (*callback)(void*), void* data, void (*free_data)(void*), bool async)
|
void Processor::smp_unicast(u32 cpu, Function<void()> callback, bool async)
|
||||||
{
|
{
|
||||||
auto& msg = smp_get_from_pool();
|
auto& msg = smp_get_from_pool();
|
||||||
msg.type = ProcessorMessage::CallbackWithData;
|
msg.type = ProcessorMessage::Callback;
|
||||||
msg.callback_with_data.handler = callback;
|
new (msg.callback_storage) ProcessorMessage::CallbackFunction(move(callback));
|
||||||
msg.callback_with_data.data = data;
|
|
||||||
msg.callback_with_data.free = free_data;
|
|
||||||
smp_unicast_message(cpu, msg, async);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Processor::smp_unicast(u32 cpu, void (*callback)(), bool async)
|
|
||||||
{
|
|
||||||
auto& msg = smp_get_from_pool();
|
|
||||||
msg.type = ProcessorMessage::CallbackWithData;
|
|
||||||
msg.callback.handler = callback;
|
|
||||||
smp_unicast_message(cpu, msg, async);
|
smp_unicast_message(cpu, msg, async);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -574,23 +574,17 @@ struct MemoryManagerData;
|
|||||||
struct ProcessorMessageEntry;
|
struct ProcessorMessageEntry;
|
||||||
|
|
||||||
struct ProcessorMessage {
|
struct ProcessorMessage {
|
||||||
|
using CallbackFunction = Function<void()>;
|
||||||
|
|
||||||
enum Type {
|
enum Type {
|
||||||
FlushTlb,
|
FlushTlb,
|
||||||
Callback,
|
Callback,
|
||||||
CallbackWithData
|
|
||||||
};
|
};
|
||||||
Type type;
|
Type type;
|
||||||
volatile u32 refs; // atomic
|
volatile u32 refs; // atomic
|
||||||
union {
|
union {
|
||||||
ProcessorMessage* next; // only valid while in the pool
|
ProcessorMessage* next; // only valid while in the pool
|
||||||
struct {
|
alignas(CallbackFunction) u8 callback_storage[sizeof(CallbackFunction)];
|
||||||
void (*handler)();
|
|
||||||
} callback;
|
|
||||||
struct {
|
|
||||||
void* data;
|
|
||||||
void (*handler)(void*);
|
|
||||||
void (*free)(void*);
|
|
||||||
} callback_with_data;
|
|
||||||
struct {
|
struct {
|
||||||
const PageDirectory* page_directory;
|
const PageDirectory* page_directory;
|
||||||
u8* ptr;
|
u8* ptr;
|
||||||
@ -601,6 +595,17 @@ struct ProcessorMessage {
|
|||||||
volatile bool async;
|
volatile bool async;
|
||||||
|
|
||||||
ProcessorMessageEntry* per_proc_entries;
|
ProcessorMessageEntry* per_proc_entries;
|
||||||
|
|
||||||
|
CallbackFunction& callback_value()
|
||||||
|
{
|
||||||
|
return *bit_cast<CallbackFunction*>(&callback_storage);
|
||||||
|
}
|
||||||
|
|
||||||
|
void invoke_callback()
|
||||||
|
{
|
||||||
|
VERIFY(type == Type::Callback);
|
||||||
|
callback_value()();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ProcessorMessageEntry {
|
struct ProcessorMessageEntry {
|
||||||
@ -942,39 +947,8 @@ public:
|
|||||||
static void smp_enable();
|
static void smp_enable();
|
||||||
bool smp_process_pending_messages();
|
bool smp_process_pending_messages();
|
||||||
|
|
||||||
template<typename Callback>
|
static void smp_broadcast(Function<void()>, bool async);
|
||||||
static void smp_broadcast(Callback callback, bool async)
|
static void smp_unicast(u32 cpu, Function<void()>, 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_flush_tlb(const PageDirectory*, VirtualAddress, size_t);
|
static void smp_broadcast_flush_tlb(const PageDirectory*, VirtualAddress, size_t);
|
||||||
static u32 smp_wake_n_idle_processors(u32 wake_count);
|
static u32 smp_wake_n_idle_processors(u32 wake_count);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user