scheduler: sched_reschedule_on_cpu

This commit is contained in:
Matheus
2024-09-17 23:23:11 -03:00
parent 698b45d31d
commit a56bfd2134
3 changed files with 50 additions and 7 deletions
+1
View File
@@ -167,6 +167,7 @@ thread_t *sched_newthread(void *ip, size_t kstacksize, int priority, proc_t *pro
void sched_destroyproc(proc_t *);
void sched_destroythread(thread_t *);
void sched_targetcpu(struct cpu_t *cpu);
void sched_reschedule_on_cpu(struct cpu_t *cpu, bool target);
void sched_sleepus(size_t us);
void sched_apentry();
void sched_inactiveproc(proc_t *proc);
+2 -7
View File
@@ -30,16 +30,11 @@ void itimer_pause(itimer_t *itimer, uintmax_t *remainingus, uintmax_t *repeatus)
bool intstatus = interrupt_set(false);
spinlock_acquire(&itimer->lock);
while (itimer->cpu && itimer->cpu != current_cpu()) {
// schedule on the itimer cpu
sched_targetcpu(itimer->cpu);
spinlock_release(&itimer->lock);
// allow interrupts to be handled (such as a tlb shootdown)
// as the other cpu could be busy waiting for this one
interrupt_set(true);
interrupt_set(false);
sched_yield();
sched_targetcpu(NULL);
sched_reschedule_on_cpu(itimer->cpu, false);
spinlock_acquire(&itimer->lock);
}
+47
View File
@@ -13,6 +13,7 @@
#include <kernel/jobctl.h>
#include <kernel/cmdline.h>
#include <kernel/auth.h>
#include <arch/smp.h>
#define QUANTUM_US 100000
#define SCHEDULER_STACK_SIZE PAGE_SIZE * 16
@@ -714,6 +715,52 @@ void sched_targetcpu(cpu_t *cpu) {
interrupt_set(intstatus);
}
// yields the current thread and sends an reschedule ipi to a specific cpu
static void reschedule_yield(context_t *context, void *_cpu) {
thread_t *thread = current_thread();
cpu_t *cpu = _cpu;
spinlock_acquire(&runqueuelock);
thread_t *next = runqueuenext(0x0fffffff);
ARCH_CONTEXT_THREADSAVE(thread, context);
thread->flags &= ~SCHED_THREAD_FLAGS_RUNNING;
runqueueinsert(thread);
if (next == NULL)
next = current_cpu()->idlethread;
arch_smp_sendipi(cpu, cpu->reschedule_isr, ARCH_SMP_IPI_TARGET, false);
spinlock_release(&runqueuelock);
switchthread(next);
}
void sched_reschedule_on_cpu(cpu_t *cpu, bool target) {
cpu_t *old_target = current_thread()->cputarget;
current_thread()->cputarget = cpu;
bool status = interrupt_set(false);
// already on the cpu
if (cpu == current_cpu())
goto leave;
long old_priority = current_thread()->priority;
current_thread()->priority = 0;
arch_context_saveandcall(reschedule_yield, current_cpu()->schedulerstack, cpu);
current_thread()->priority = old_priority;
leave:
interrupt_set(status);
if (target == false)
current_thread()->cputarget = old_target;
}
static void timeout(context_t *, dpcarg_t arg) {
thread_t *thread = arg;
sched_wakeup(thread, 0);