From e698cfdfd16bae08cb33c73bb575c89ec8c062ba Mon Sep 17 00:00:00 2001 From: Benji Dial Date: Sun, 28 Dec 2025 20:27:00 -0500 Subject: [PATCH] kernel: fix race condition in input component --- src/kernel/input.c | 7 +++++-- src/kernel/input.h | 1 + src/kernel/scheduler.asm | 18 ++++++++++++++++++ src/kernel/scheduler.h | 3 +++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/kernel/input.c b/src/kernel/input.c index 4c24293..0913696 100644 --- a/src/kernel/input.c +++ b/src/kernel/input.c @@ -38,6 +38,7 @@ void add_mouse_movement(int x, int y) { add_to_queue(&ready_continuations, &waiting_continuation); total_unreported_x_movement = 0; total_unreported_y_movement = 0; + is_somebody_waiting_for_mouse_packet = 0; } } @@ -46,6 +47,8 @@ void syscall_wait_for_mouse_packet(struct mouse_packet *packet_out) { assert(running_thread != 0); + __asm__ ("cli"); + //TODO: handle these if (is_somebody_waiting_for_mouse_packet || !is_mapped_writable( @@ -57,12 +60,12 @@ void syscall_wait_for_mouse_packet(struct mouse_packet *packet_out) { packet_out->y_change = total_unreported_y_movement; total_unreported_x_movement = 0; total_unreported_y_movement = 0; + __asm__ ("sti"); return; } is_somebody_waiting_for_mouse_packet = 1; resume_by_reporting_to = packet_out; - yield(&waiting_continuation); - is_somebody_waiting_for_mouse_packet = 0; + yield_sti(&waiting_continuation); } diff --git a/src/kernel/input.h b/src/kernel/input.h index bb5970b..65059b0 100644 --- a/src/kernel/input.h +++ b/src/kernel/input.h @@ -19,6 +19,7 @@ #include +//should only be called with interrupts disabled void add_mouse_movement(int x, int y); void syscall_wait_for_mouse_packet(struct mouse_packet *packet_out); diff --git a/src/kernel/scheduler.asm b/src/kernel/scheduler.asm index aefc835..76b16f6 100644 --- a/src/kernel/scheduler.asm +++ b/src/kernel/scheduler.asm @@ -53,3 +53,21 @@ yield: .ret: ret + +global yield_sti +yield_sti: + mov qword [rdi], ret + mov qword [rdi + 8], rbx + mov qword [rdi + 16], rbp + mov qword [rdi + 24], rsp + mov qword [rdi + 32], r12 + mov qword [rdi + 40], r13 + mov qword [rdi + 48], r14 + mov qword [rdi + 56], r15 + + sti + + jmp resume_next_continuation + +.ret: + ret diff --git a/src/kernel/scheduler.h b/src/kernel/scheduler.h index cac8936..febefd2 100644 --- a/src/kernel/scheduler.h +++ b/src/kernel/scheduler.h @@ -54,3 +54,6 @@ int take_from_queue(struct continuation_queue *queue, struct continuation_info * //saves a continuation that returns from this function to save_current_continuation_to, then resumes //the next ready continuation (thus doesn't return until save_current_continuation_to is resumed). void yield(struct continuation_info *save_current_continuation_to); + +//save as yield but enables interrupts between saving this continuation and resuming next ready one. +void yield_sti(struct continuation_info *save_current_continuation_to);