add statefull scheduler and syscall routine
All checks were successful
continuous-integration/drone/push Build is passing

Signed-off-by: Julien CLEMENT <julien.clement@epita.fr>
This commit is contained in:
Julien CLEMENT 2023-01-04 21:45:22 +01:00
parent 689f7c8810
commit 1bb4074e2f
4 changed files with 67 additions and 14 deletions

@ -1,3 +1,4 @@
use crate::println;
use crate::utils::mutex::AsyncMutex; use crate::utils::mutex::AsyncMutex;
use super::thread::{Thread, ThreadId}; use super::thread::{Thread, ThreadId};
@ -77,6 +78,7 @@ impl Scheduler {
started: true, started: true,
rsp: 0, rsp: 0,
base_stack: 0, base_stack: 0,
is_blocked: false,
}; };
res.register(Arc::new(RefCell::new(k_thread))); res.register(Arc::new(RefCell::new(k_thread)));
res res
@ -86,13 +88,22 @@ impl Scheduler {
while let Some(id) = self.thread_queue.next().await { while let Some(id) = self.thread_queue.next().await {
if let Some(thread) = self.get_thread(id) { if let Some(thread) = self.get_thread(id) {
// Thread still exists // Thread still exists
let blocked: bool;
{
blocked = thread.borrow().is_blocked;
} // Drop thread borrow
if !blocked {
unsafe { unsafe {
(&mut *thread.as_ptr()).run(); (&mut *thread.as_ptr()).run();
} }
if !thread.borrow().is_blocked {
self.thread_queue.register(id); self.thread_queue.register(id);
} }
} }
} }
}
}
pub fn register(&mut self, thread: Threadt) { pub fn register(&mut self, thread: Threadt) {
let thread_id = thread.borrow().id; let thread_id = thread.borrow().id;
@ -104,6 +115,21 @@ impl Scheduler {
} }
} }
pub fn block(&mut self, id: ThreadId) {
if let Some(thread) = self.get_thread(id) {
thread.borrow_mut().is_blocked = true;
println!("Blocked thread {:?}", id);
}
}
pub fn unblock(&mut self, id: ThreadId) {
if let Some(thread) = self.get_thread(id) {
thread.borrow_mut().is_blocked = false;
self.thread_queue.register(id);
println!("Unblocked thread {:?}", id);
}
}
pub fn exit(&mut self, id: ThreadId) { pub fn exit(&mut self, id: ThreadId) {
self.threads.remove(&id).unwrap().borrow().exit(); self.threads.remove(&id).unwrap().borrow().exit();
} }

@ -25,10 +25,10 @@ impl ThreadId {
} }
} }
pub async fn resume_k_thread() { pub fn resume_k_thread() {
let k_thread: *mut Thread; let k_thread: *mut Thread;
{ {
let mut scheduler = SCHEDULER.lock().await; let mut scheduler = SCHEDULER.try_lock().unwrap();
k_thread = scheduler.get_thread(K_THREAD_ID).unwrap().as_ptr(); k_thread = scheduler.get_thread(K_THREAD_ID).unwrap().as_ptr();
} // Drop scheduler mutex guard } // Drop scheduler mutex guard
@ -40,6 +40,7 @@ pub async fn resume_k_thread() {
pub fn routine() { pub fn routine() {
println!("Routine executed"); println!("Routine executed");
crate::syscalls::syscall_routine(crate::syscalls::EXIT_ID); // Call exit crate::syscalls::syscall_routine(crate::syscalls::EXIT_ID); // Call exit
println!("SHOULD NEVER BE DISPLAYED");
} }
pub struct Thread { pub struct Thread {
@ -48,6 +49,7 @@ pub struct Thread {
pub started: bool, pub started: bool,
pub rsp: u64, pub rsp: u64,
pub base_stack: u64, pub base_stack: u64,
pub is_blocked: bool,
} }
impl Thread { impl Thread {
@ -60,6 +62,7 @@ impl Thread {
started: false, started: false,
rsp: stack_bottom + STACK_SIZE as u64, rsp: stack_bottom + STACK_SIZE as u64,
base_stack: stack_bottom, base_stack: stack_bottom,
is_blocked: false
} }
} }
} }

@ -1,4 +1,6 @@
use crate::println;
use crate::proc::thread::{resume_k_thread, RUNNING_THREAD}; use crate::proc::thread::{resume_k_thread, RUNNING_THREAD};
use crate::proc::scheduler::SCHEDULER;
use crate::task::executor::EXECUTOR; use crate::task::executor::EXECUTOR;
use crate::task::Task; use crate::task::Task;
@ -19,25 +21,47 @@ pub struct SyscallContext {
thread_id: crate::proc::thread::ThreadId, thread_id: crate::proc::thread::ThreadId,
} }
pub fn syscall_dispatcher(context: SyscallContextT) -> Task { impl SyscallContext {
match context.borrow().id { pub async fn run(&mut self) {
EXIT_ID => Task::new(proc::exit(context.clone())), println!("Running async syscall runner");
_ => Task::new(bad_syscall()), self.dispatch().await;
println!("Syscall end, unblocking thread");
SCHEDULER.lock().await.unblock(self.thread_id);
}
pub async fn dispatch(&mut self) {
match self.id {
EXIT_ID => proc::exit(self).await,
_ => bad_syscall().await,
}
} }
} }
async fn syscall_runner(context: SyscallContextT) {
context.borrow_mut().run().await;
}
pub fn syscall_routine(syscall_id: SyscallId) -> u64 { pub fn syscall_routine(syscall_id: SyscallId) -> u64 {
println!("Running syscall");
let context: SyscallContextT = Arc::new(RefCell::new(SyscallContext { let context: SyscallContextT = Arc::new(RefCell::new(SyscallContext {
id: syscall_id, id: syscall_id,
res: 0, res: 0,
thread_id: *RUNNING_THREAD.try_lock().unwrap(), thread_id: *RUNNING_THREAD.try_lock().unwrap(),
})); }));
println!("Spawning async syscall runner");
EXECUTOR EXECUTOR
.try_lock() .try_lock()
.unwrap() .unwrap()
.spawn(syscall_dispatcher(context.clone())); .spawn(Task::new(syscall_runner(context.clone())));
println!("Blocking thread");
SCHEDULER
.try_lock()
.unwrap()
.block(context.borrow().thread_id);
println!("Returning to scheduler");
resume_k_thread(); resume_k_thread();
let res = context.borrow().res; let res = context.borrow().res;

@ -1,10 +1,10 @@
use crate::println; use crate::println;
use crate::proc::scheduler::SCHEDULER; use crate::proc::scheduler::SCHEDULER;
use super::SyscallContextT; use super::SyscallContext;
pub async fn exit(context: SyscallContextT) { pub async fn exit(context: &SyscallContext) {
println!("Exiting thread"); println!("Running exit(2)");
let mut scheduler = SCHEDULER.lock().await; let mut scheduler = SCHEDULER.lock().await;
scheduler.exit(context.borrow().thread_id); scheduler.exit(context.thread_id);
} }