diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index d93b2a55..f0f7d130 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -237,8 +237,7 @@ void irq_handler(struct state *s) // evaluate only irq status register if int_no = 124 if( s->int_no == 124 ) { check_workqueues_rem_irq(); - } - else { + } else { check_workqueues(); } @@ -283,4 +282,6 @@ leave_handler: // timer interrupt? if ((s->int_no == 32) || (s->int_no == 123)) scheduler(); // switch to a new task + else if ((s->int_no >= 32) && (get_highest_priority() > per_core(current_task)->prio)) + scheduler(); } diff --git a/include/metalsvm/tasks.h b/include/metalsvm/tasks.h index 8dd950f8..3f4589cb 100644 --- a/include/metalsvm/tasks.h +++ b/include/metalsvm/tasks.h @@ -180,6 +180,14 @@ int sys_execve(const char* fname, char** argv, char** env); */ void check_scheduling(void); +/** @brief determine the highest priority of all tasks, which are ready + * + * @return + * - return highest priority + * - if no task is ready, the function returns an invalid value (> MAX_PRIO) + */ +uint32_t get_highest_priority(void); + /** @brief Call to rescheduling * * This is a purely assembled procedure for rescheduling diff --git a/kernel/tasks.c b/kernel/tasks.c index 910a0605..10f4a50a 100644 --- a/kernel/tasks.c +++ b/kernel/tasks.c @@ -75,6 +75,11 @@ void check_scheduling(void) { reschedule(); } +uint32_t get_highest_priority(void) +{ + return msb(runqueues[CORE_ID].prio_bitmap); +} + int multitasking_init(void) { if (BUILTIN_EXPECT(task_table[0].status != TASK_IDLE, 0)) { kputs("Task 0 is not an idle task\n");