mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 23:18:21 +00:00
scheduler: slightly redo how the preemption dpc is enqueued and add a skeleton for a rescheduling ipi
This commit is contained in:
@@ -30,9 +30,14 @@ typedef struct cpu_t {
|
|||||||
thread_t *idlethread;
|
thread_t *idlethread;
|
||||||
timerentry_t schedtimerentry;
|
timerentry_t schedtimerentry;
|
||||||
void *schedulerstack;
|
void *schedulerstack;
|
||||||
|
|
||||||
isr_t *isrqueue;
|
isr_t *isrqueue;
|
||||||
dpc_t *dpcqueue;
|
|
||||||
isr_t *dpcisr;
|
isr_t *dpcisr;
|
||||||
|
dpc_t *dpcqueue;
|
||||||
|
|
||||||
|
dpc_t reschedule_dpc;
|
||||||
|
isr_t *reschedule_isr;
|
||||||
} cpu_t;
|
} cpu_t;
|
||||||
|
|
||||||
#define CPU_HALT() asm volatile("hlt")
|
#define CPU_HALT() asm volatile("hlt")
|
||||||
|
|||||||
@@ -602,6 +602,7 @@ bool sched_wakeup(thread_t *thread, int reason) {
|
|||||||
thread->flags &= ~(SCHED_THREAD_FLAGS_SLEEP | SCHED_THREAD_FLAGS_INTERRUPTIBLE);
|
thread->flags &= ~(SCHED_THREAD_FLAGS_SLEEP | SCHED_THREAD_FLAGS_INTERRUPTIBLE);
|
||||||
thread->wakeupreason = reason;
|
thread->wakeupreason = reason;
|
||||||
|
|
||||||
|
// TODO send IPI to idle cores
|
||||||
sched_queue(thread);
|
sched_queue(thread);
|
||||||
spinlock_release(&thread->sleeplock);
|
spinlock_release(&thread->sleeplock);
|
||||||
interrupt_set(intstate);
|
interrupt_set(intstate);
|
||||||
@@ -672,7 +673,7 @@ static void dopreempt() {
|
|||||||
switchthread(next);
|
switchthread(next);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void timerhook(context_t *context, dpcarg_t arg) {
|
static void preempt_dpc(context_t *context, dpcarg_t arg) {
|
||||||
thread_t* current = current_thread();
|
thread_t* current = current_thread();
|
||||||
interrupt_set(false);
|
interrupt_set(false);
|
||||||
|
|
||||||
@@ -688,6 +689,16 @@ static void timerhook(context_t *context, dpcarg_t arg) {
|
|||||||
CTX_IP(context) = (uintptr_t)dopreempt;
|
CTX_IP(context) = (uintptr_t)dopreempt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IPL_DPC
|
||||||
|
static void reschedule_timer_dpc(context_t *context, dpcarg_t arg) {
|
||||||
|
dpc_enqueue(¤t_cpu()->reschedule_dpc, preempt_dpc, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPL_MAX
|
||||||
|
static void reschedule_ipi(isr_t *, context_t *) {
|
||||||
|
dpc_enqueue(¤t_cpu()->reschedule_dpc, preempt_dpc, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static void cpuidlethread() {
|
static void cpuidlethread() {
|
||||||
sched_targetcpu(current_cpu());
|
sched_targetcpu(current_cpu());
|
||||||
interrupt_set(true);
|
interrupt_set(true);
|
||||||
@@ -724,7 +735,10 @@ void sched_apentry() {
|
|||||||
current_cpu()->idlethread = sched_newthread(cpuidlethread, PAGE_SIZE * 4, 3, NULL, NULL);
|
current_cpu()->idlethread = sched_newthread(cpuidlethread, PAGE_SIZE * 4, 3, NULL, NULL);
|
||||||
__assert(current_cpu()->idlethread);
|
__assert(current_cpu()->idlethread);
|
||||||
|
|
||||||
timer_insert(current_cpu()->timer, ¤t_cpu()->schedtimerentry, timerhook, NULL, QUANTUM_US, true);
|
current_cpu()->reschedule_isr = interrupt_allocate(reschedule_ipi, ARCH_EOI, IPL_MAX);
|
||||||
|
__assert(current_cpu()->reschedule_isr);
|
||||||
|
|
||||||
|
timer_insert(current_cpu()->timer, ¤t_cpu()->schedtimerentry, reschedule_timer_dpc, NULL, QUANTUM_US, true);
|
||||||
timer_resume(current_cpu()->timer);
|
timer_resume(current_cpu()->timer);
|
||||||
sched_stopcurrentthread();
|
sched_stopcurrentthread();
|
||||||
}
|
}
|
||||||
@@ -749,7 +763,10 @@ void sched_init() {
|
|||||||
current_cpu()->thread = sched_newthread(NULL, PAGE_SIZE * 32, 0, NULL, NULL);
|
current_cpu()->thread = sched_newthread(NULL, PAGE_SIZE * 32, 0, NULL, NULL);
|
||||||
__assert(current_thread());
|
__assert(current_thread());
|
||||||
|
|
||||||
timer_insert(current_cpu()->timer, ¤t_cpu()->schedtimerentry, timerhook, NULL, QUANTUM_US, true);
|
current_cpu()->reschedule_isr = interrupt_allocate(reschedule_ipi, ARCH_EOI, IPL_MAX);
|
||||||
|
__assert(current_cpu()->reschedule_isr);
|
||||||
|
|
||||||
|
timer_insert(current_cpu()->timer, ¤t_cpu()->schedtimerentry, reschedule_timer_dpc, NULL, QUANTUM_US, true);
|
||||||
// XXX move this resume to a more appropriate place
|
// XXX move this resume to a more appropriate place
|
||||||
timer_resume(current_cpu()->timer);
|
timer_resume(current_cpu()->timer);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user