kernel: fix race condition in input component
This commit is contained in:
parent
e2188aa407
commit
e698cfdfd1
4 changed files with 27 additions and 2 deletions
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include <kernel-public/input.h>
|
||||
|
||||
//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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue