1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-06-01 10:08:10 +00:00

Kernel: Introduce ProcessorSpecific<T> for per-CPU data structures

To add a new per-CPU data structure, add an ID for it to the
ProcessorSpecificDataID enum.

Then call ProcessorSpecific<T>::initialize() when you are ready to
construct the per-CPU data structure on the current CPU. It can then
be accessed via ProcessorSpecific<T>::get().

This patch replaces the existing hard-coded mechanisms for Scheduler
and MemoryManager per-CPU data structure.
This commit is contained in:
Andreas Kling 2021-07-27 14:30:26 +02:00
parent 559ab00249
commit 1e43292c3b
6 changed files with 46 additions and 38 deletions

View file

@ -21,10 +21,14 @@
namespace Kernel {
class ProcessorInfo;
class SchedulerPerProcessorData;
struct MemoryManagerData;
struct ProcessorMessageEntry;
enum class ProcessorSpecificDataID {
MemoryManager,
Scheduler,
__Count,
};
#if ARCH(X86_64)
# define MSR_FS_BASE 0xc0000100
# define MSR_GS_BASE 0xc0000101
@ -127,8 +131,6 @@ class Processor {
u8 m_physical_address_bit_width;
ProcessorInfo* m_info;
MemoryManagerData* m_mm_data;
SchedulerPerProcessorData* m_scheduler_data;
Thread* m_current_thread;
Thread* m_idle_thread;
@ -142,6 +144,8 @@ class Processor {
DeferredCallEntry* m_free_deferred_call_pool_entry;
DeferredCallEntry m_deferred_call_pool[5];
void* m_processor_specific_data[(size_t)ProcessorSpecificDataID::__Count];
void gdt_init();
void write_raw_gdt_entry(u16 selector, u32 low, u32 high);
void write_gdt_entry(u16 selector, Descriptor& descriptor);
@ -259,24 +263,15 @@ public:
read_gs_ptr(__builtin_offsetof(Processor, m_self)) != 0;
}
ALWAYS_INLINE void set_scheduler_data(SchedulerPerProcessorData& scheduler_data)
template<typename T>
T* get_specific()
{
m_scheduler_data = &scheduler_data;
return static_cast<T*>(m_processor_specific_data[static_cast<size_t>(T::processor_specific_data_id())]);
}
ALWAYS_INLINE SchedulerPerProcessorData& get_scheduler_data() const
void set_specific(ProcessorSpecificDataID specific_id, void* ptr)
{
return *m_scheduler_data;
}
ALWAYS_INLINE void set_mm_data(MemoryManagerData& mm_data)
{
m_mm_data = &mm_data;
}
ALWAYS_INLINE MemoryManagerData& get_mm_data() const
{
return *m_mm_data;
m_processor_specific_data[static_cast<size_t>(specific_id)] = ptr;
}
ALWAYS_INLINE void set_idle_thread(Thread& idle_thread)
@ -449,4 +444,17 @@ public:
String platform_string() const;
};
template<typename T>
class ProcessorSpecific {
public:
static void initialize()
{
Processor::current().set_specific(T::processor_specific_data_id(), new T);
}
static T& get()
{
return *Processor::current().get_specific<T>();
}
};
}

View file

@ -304,8 +304,6 @@ UNMAP_AFTER_INIT void Processor::early_initialize(u32 cpu)
m_message_queue = nullptr;
m_idle_thread = nullptr;
m_current_thread = nullptr;
m_scheduler_data = nullptr;
m_mm_data = nullptr;
m_info = nullptr;
m_halt_requested = false;