kernel: Use local APIC timer for preemption on APs, not an IPI
This commit is contained in:
parent
8994db92f3
commit
f7a29b90af
@ -256,19 +256,27 @@ void arch_tick_others(void);
|
||||
|
||||
static uint64_t time_slice_basis = 0;
|
||||
|
||||
int cmos_time_stuff(struct regs *r) {
|
||||
static spin_lock_t clock_lock = { 0 };
|
||||
void arch_update_clock(void) {
|
||||
uint64_t clock_ticks = read_tsc() / tsc_mhz;
|
||||
uint64_t timer_ticks, timer_subticks;
|
||||
spin_lock(clock_lock);
|
||||
update_ticks(clock_ticks, &timer_ticks, &timer_subticks);
|
||||
wakeup_sleepers(timer_ticks, timer_subticks);
|
||||
irq_ack(0);
|
||||
|
||||
if (time_slice_basis + SUBSECONDS_PER_SECOND/4 <= clock_ticks) {
|
||||
update_process_usage(clock_ticks - time_slice_basis, tsc_mhz);
|
||||
time_slice_basis = clock_ticks;
|
||||
}
|
||||
spin_unlock(clock_lock);
|
||||
|
||||
wakeup_sleepers(timer_ticks, timer_subticks);
|
||||
|
||||
}
|
||||
|
||||
int cmos_time_stuff(struct regs *r) {
|
||||
arch_update_clock();
|
||||
|
||||
irq_ack(0);
|
||||
|
||||
arch_tick_others();
|
||||
switch_task(1);
|
||||
asm volatile (
|
||||
".global _ret_from_preempt_source\n"
|
||||
|
@ -339,6 +339,8 @@ struct regs * isr_handler(struct regs * r) {
|
||||
return r;
|
||||
}
|
||||
case 123: {
|
||||
extern void arch_update_clock(void);
|
||||
arch_update_clock();
|
||||
switch_task(1);
|
||||
return r;
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <kernel/printf.h>
|
||||
#include <kernel/misc.h>
|
||||
#include <kernel/args.h>
|
||||
#include <kernel/time.h>
|
||||
#include <kernel/multiboot.h>
|
||||
#include <kernel/arch/x86_64/acpi.h>
|
||||
#include <kernel/arch/x86_64/mmu.h>
|
||||
@ -123,6 +124,20 @@ void ap_main(void) {
|
||||
|
||||
/* Enable our spurious vector register */
|
||||
*((volatile uint32_t*)(lapic_final + 0x0F0)) = 0x127;
|
||||
*((volatile uint32_t*)(lapic_final + 0x320)) = 0x7b;
|
||||
*((volatile uint32_t*)(lapic_final + 0x3e0)) = 1;
|
||||
|
||||
uint64_t before = arch_perf_timer();
|
||||
*((volatile uint32_t*)(lapic_final + 0x380)) = 1000000;
|
||||
while (*((volatile uint32_t*)(lapic_final + 0x390)));
|
||||
uint64_t after = arch_perf_timer();
|
||||
|
||||
uint64_t ms = (after-before)/arch_cpu_mhz();
|
||||
uint64_t target = 10000000000UL / ms;
|
||||
|
||||
*((volatile uint32_t*)(lapic_final + 0x3e0)) = 1;
|
||||
*((volatile uint32_t*)(lapic_final + 0x320)) = 0x7b | 0x20000;
|
||||
*((volatile uint32_t*)(lapic_final + 0x380)) = target;
|
||||
|
||||
/* Set our pml pointers */
|
||||
this_core->current_pml = &init_page_region[0];
|
||||
|
Loading…
x
Reference in New Issue
Block a user