Add suuport for sleeping processes and a syscall to sleep waiting for IPC

This commit is contained in:
pjht 2024-06-08 06:54:53 -05:00
parent 8bbc165e58
commit 1376aa5f44
Signed by: pjht
GPG Key ID: 7B5F6AFBEC7EE78E
2 changed files with 45 additions and 8 deletions

View File

@ -1,5 +1,5 @@
use crate::{ use crate::{
bootinfo::BOOTINFO, dbg, print, println, virtual_memory::{ASpaceMutex, AddressSpace, ACTIVE_SPACE, KERNEL_SPACE}, TASKING bootinfo::BOOTINFO, dbg, print, println, tasking::SleepReason, virtual_memory::{ASpaceMutex, AddressSpace, ACTIVE_SPACE, KERNEL_SPACE}, TASKING
}; };
use alloc::{boxed::Box, vec::Vec}; use alloc::{boxed::Box, vec::Vec};
use core::{arch::asm, ptr::{addr_of, slice_from_raw_parts_mut}, slice, str}; use core::{arch::asm, ptr::{addr_of, slice_from_raw_parts_mut}, slice, str};
@ -312,16 +312,20 @@ extern "C" fn syscall_handler() {
} }
} }
11 => { 11 => {
let pid = regs.rcx as usize;
if let Some(buffer) = get_buffer(regs.rdx) { if let Some(buffer) = get_buffer(regs.rdx) {
assert!(regs.rsi as usize <= buffer.len()); assert!(regs.rsi as usize <= buffer.len());
let mut tasking = TASKING.lock(); let mut tasking = TASKING.lock();
if let Some(_queue) = tasking.message_queue_mut(regs.rcx as usize) { if let Some(_queue) = tasking.message_queue_mut(pid) {
let len = regs.rsi as usize; let len = regs.rsi as usize;
let buffer = Box::into_raw(buffer); let buffer = Box::into_raw(buffer);
let new_buffer_key = let new_buffer_key =
tasking.proc_data_buffers_mut(regs.rcx as usize).insert(buffer); tasking.proc_data_buffers_mut(pid).insert(buffer);
let queue = tasking.message_queue_mut(regs.rcx as usize).unwrap(); let queue = tasking.message_queue_mut(pid).unwrap();
queue.push((new_buffer_key, len)); queue.push((new_buffer_key, len));
if tasking.proc_sleeping(pid) == Some(SleepReason::WaitingForIPC) {
tasking.wake(pid);
}
retval = 0; retval = 0;
} else { } else {
retval = 1; retval = 1;
@ -380,9 +384,16 @@ extern "C" fn syscall_handler() {
let space = tasking.address_spaces_mut().get_mut((regs.rcx - 1) as usize).unwrap(); let space = tasking.address_spaces_mut().get_mut((regs.rcx - 1) as usize).unwrap();
space.run(|| unsafe { slice::from_raw_parts_mut(regs.rdx as *mut u8, regs.rsi as usize).fill(0) }); space.run(|| unsafe { slice::from_raw_parts_mut(regs.rdx as *mut u8, regs.rsi as usize).fill(0) });
retval = 0; retval = 0;
},
18 => {
let mut tasking = TASKING.lock();
if tasking.current_message_queue_mut().is_empty() {
tasking.sleep(SleepReason::WaitingForIPC);
}
} }
_ => (), _ => (),
}; };
unsafe { SYSCALL_REGS = regs };
unsafe { unsafe {
asm!( asm!(
"mov rbx, [rip+SYSCALL_REGS+8]", "mov rbx, [rip+SYSCALL_REGS+8]",

View File

@ -1,6 +1,5 @@
use crate::{ use crate::{
gdt, println, qemu_exit, dbg, gdt, println, qemu_exit, virtual_memory::{ASpaceMutex, AddressSpace, PagingError, KERNEL_SPACE}
virtual_memory::{ASpaceMutex, AddressSpace, PagingError, KERNEL_SPACE},
}; };
use alloc::{boxed::Box, vec::Vec}; use alloc::{boxed::Box, vec::Vec};
use core::{arch::asm, ptr::addr_of}; use core::{arch::asm, ptr::addr_of};
@ -77,6 +76,11 @@ extern "C" fn task_force_unlock() {
interrupts::enable(); interrupts::enable();
} }
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum SleepReason {
WaitingForIPC,
}
#[derive(Debug)] #[derive(Debug)]
struct Process { struct Process {
kernel_stack: Box<[usize], &'static ASpaceMutex>, kernel_stack: Box<[usize], &'static ASpaceMutex>,
@ -86,6 +90,7 @@ struct Process {
address_spaces: Slab<AddressSpace>, address_spaces: Slab<AddressSpace>,
data_buffers: Slab<*mut [u8]>, data_buffers: Slab<*mut [u8]>,
message_queue: SegQueue<(usize, usize)>, message_queue: SegQueue<(usize, usize)>,
sleeping: Option<SleepReason>
} }
unsafe impl Send for Process {} unsafe impl Send for Process {}
@ -129,6 +134,7 @@ impl Tasking {
address_spaces: Slab::new(), address_spaces: Slab::new(),
data_buffers: Slab::new(), data_buffers: Slab::new(),
message_queue: SegQueue::new(), message_queue: SegQueue::new(),
sleeping: None,
}); });
self.ready_to_run.push(pid); self.ready_to_run.push(pid);
Ok(pid) Ok(pid)
@ -149,10 +155,14 @@ impl Tasking {
self.processes[current_process].address_space = Some(current_address_space); self.processes[current_process].address_space = Some(current_address_space);
let next_process = &self.processes[next_process_pid]; let next_process = &self.processes[next_process_pid];
gdt::set_tss_stack(next_process.kernel_esp_top); gdt::set_tss_stack(next_process.kernel_esp_top);
self.ready_to_run.push(current_process); if self.processes[current_process].sleeping.is_none() {
self.ready_to_run.push(current_process);
}
let kernel_esp = next_process.kernel_esp; let kernel_esp = next_process.kernel_esp;
let previous_process = self.current_process.replace(next_process_pid).unwrap(); let previous_process = self.current_process.replace(next_process_pid).unwrap();
switch_to_asm(&mut (self.processes[previous_process].kernel_esp), kernel_esp); switch_to_asm(&mut (self.processes[previous_process].kernel_esp), kernel_esp);
} else if self.processes[current_process].sleeping.is_some() {
qemu_exit::exit_qemu();
} }
} }
@ -177,7 +187,7 @@ impl Tasking {
switch_to_asm_exit(kernel_esp); switch_to_asm_exit(kernel_esp);
unreachable!() unreachable!()
} else { } else {
println!("Last process exited, exiting QEMU"); println!("Last non-sleeping process exited, exiting QEMU");
qemu_exit::exit_qemu(); qemu_exit::exit_qemu();
} }
} }
@ -201,4 +211,20 @@ impl Tasking {
pub fn message_queue_mut(&mut self, pid: usize) -> Option<&mut SegQueue<(usize, usize)>> { pub fn message_queue_mut(&mut self, pid: usize) -> Option<&mut SegQueue<(usize, usize)>> {
Some(&mut self.processes.get_mut(pid)?.message_queue) Some(&mut self.processes.get_mut(pid)?.message_queue)
} }
pub fn proc_sleeping(&mut self, pid: usize) -> Option<SleepReason> {
self.processes[pid].sleeping
}
pub fn sleep(&mut self, reason: SleepReason) {
self.processes[self.current_process.unwrap()].sleeping = Some(reason);
self.task_yield();
}
pub fn wake(&mut self, pid: usize) {
if self.processes[pid].sleeping.is_some() {
self.processes[pid].sleeping = None;
self.ready_to_run.push(pid);
}
}
} }