Kernel: All processors use LAPIC timer when running with APIC
This makes scheduler preemption much cleaner as bsb does not have to send smp messages to notify other processes about timer interrupt. Also PIT percision is now "full" 0.8 us instead of 1 ms that I was using before.
This commit is contained in:
@@ -23,6 +23,8 @@ namespace Kernel
|
||||
virtual void broadcast_ipi() override;
|
||||
virtual void enable() override;
|
||||
|
||||
void initialize_timer();
|
||||
|
||||
private:
|
||||
uint32_t read_from_local_apic(ptrdiff_t);
|
||||
void write_to_local_apic(ptrdiff_t, uint32_t);
|
||||
@@ -58,13 +60,14 @@ namespace Kernel
|
||||
};
|
||||
|
||||
private:
|
||||
SpinLock m_lock;
|
||||
BAN::Vector<Processor> m_processors;
|
||||
Kernel::paddr_t m_local_apic_paddr = 0;
|
||||
Kernel::vaddr_t m_local_apic_vaddr = 0;
|
||||
BAN::Vector<IOAPIC> m_io_apics;
|
||||
uint8_t m_irq_overrides[0x100] {};
|
||||
uint8_t m_reserved_gsis[0x100 / 8] {};
|
||||
SpinLock m_lock;
|
||||
BAN::Vector<Processor> m_processors;
|
||||
Kernel::paddr_t m_local_apic_paddr = 0;
|
||||
Kernel::vaddr_t m_local_apic_vaddr = 0;
|
||||
BAN::Vector<IOAPIC> m_io_apics;
|
||||
uint8_t m_irq_overrides[0x100] {};
|
||||
uint8_t m_reserved_gsis[0x100 / 8] {};
|
||||
uint64_t m_lapic_timer_frequency_hz { 0 };
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -7,9 +7,10 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
constexpr uint8_t IRQ_VECTOR_BASE = 0x20;
|
||||
constexpr uint8_t IRQ_VECTOR_BASE = 0x20;
|
||||
constexpr uint8_t IRQ_YIELD = 32;
|
||||
constexpr uint8_t IRQ_IPI = 33;
|
||||
constexpr uint8_t IRQ_TIMER = 34;
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
@@ -56,8 +56,6 @@ namespace Kernel
|
||||
FlushTLB,
|
||||
NewThread,
|
||||
UnblockThread,
|
||||
// FIXME: all processors should LAPIC for their preemption
|
||||
SchedulerPreemption,
|
||||
};
|
||||
SMPMessage* next { nullptr };
|
||||
Type type;
|
||||
|
||||
@@ -110,8 +110,6 @@ namespace Kernel
|
||||
|
||||
class ProcessorID find_least_loaded_processor() const;
|
||||
|
||||
void preempt();
|
||||
|
||||
void handle_unblock_request(const UnblockRequest&);
|
||||
void handle_new_thread_request(const NewThreadRequest&);
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ namespace Kernel
|
||||
virtual uint64_t ns_since_boot() const override;
|
||||
virtual timespec time_since_boot() const override;
|
||||
|
||||
virtual void pre_scheduler_sleep_ns(uint64_t) override;
|
||||
|
||||
virtual void handle_irq() override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -16,15 +16,18 @@ namespace Kernel
|
||||
virtual uint64_t ns_since_boot() const override;
|
||||
virtual timespec time_since_boot() const override;
|
||||
|
||||
virtual void pre_scheduler_sleep_ns(uint64_t) override;
|
||||
|
||||
virtual void handle_irq() override;
|
||||
|
||||
private:
|
||||
void initialize();
|
||||
uint64_t read_counter() const;
|
||||
|
||||
uint64_t read_counter_ns() const;
|
||||
|
||||
private:
|
||||
mutable SpinLock m_lock;
|
||||
uint64_t m_system_time { 0 };
|
||||
uint64_t m_system_time_ms { 0 };
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,16 @@ namespace Kernel
|
||||
virtual uint64_t ms_since_boot() const = 0;
|
||||
virtual uint64_t ns_since_boot() const = 0;
|
||||
virtual timespec time_since_boot() const = 0;
|
||||
|
||||
virtual void pre_scheduler_sleep_ns(uint64_t) = 0;
|
||||
|
||||
void dont_invoke_scheduler() { m_should_invoke_scheduler = false; }
|
||||
|
||||
protected:
|
||||
bool should_invoke_scheduler() const { return m_should_invoke_scheduler; }
|
||||
|
||||
private:
|
||||
bool m_should_invoke_scheduler { true };
|
||||
};
|
||||
|
||||
class SystemTimer : public Timer
|
||||
@@ -29,6 +39,8 @@ namespace Kernel
|
||||
virtual uint64_t ns_since_boot() const override;
|
||||
virtual timespec time_since_boot() const override;
|
||||
|
||||
virtual void pre_scheduler_sleep_ns(uint64_t) override;
|
||||
|
||||
void sleep_ms(uint64_t ms) const { return sleep_ns(ms * 1'000'000); }
|
||||
void sleep_ns(uint64_t ns) const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user