diff --git a/src/proc/scheduler/mod.rs b/src/proc/scheduler/mod.rs index f4d4991..7d09de8 100644 --- a/src/proc/scheduler/mod.rs +++ b/src/proc/scheduler/mod.rs @@ -1,3 +1,4 @@ +use crate::println; use crate::utils::mutex::AsyncMutex; use super::thread::{Thread, ThreadId}; @@ -77,6 +78,7 @@ impl Scheduler { started: true, rsp: 0, base_stack: 0, + is_blocked: false, }; res.register(Arc::new(RefCell::new(k_thread))); res @@ -86,10 +88,19 @@ impl Scheduler { while let Some(id) = self.thread_queue.next().await { if let Some(thread) = self.get_thread(id) { // Thread still exists - unsafe { - (&mut *thread.as_ptr()).run(); + let blocked: bool; + { + blocked = thread.borrow().is_blocked; + } // Drop thread borrow + if !blocked { + unsafe { + (&mut *thread.as_ptr()).run(); + } + + if !thread.borrow().is_blocked { + self.thread_queue.register(id); + } } - self.thread_queue.register(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) { self.threads.remove(&id).unwrap().borrow().exit(); } diff --git a/src/proc/thread/mod.rs b/src/proc/thread/mod.rs index 53fbdf7..23d777b 100644 --- a/src/proc/thread/mod.rs +++ b/src/proc/thread/mod.rs @@ -25,10 +25,10 @@ impl ThreadId { } } -pub async fn resume_k_thread() { +pub fn resume_k_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(); } // Drop scheduler mutex guard @@ -40,6 +40,7 @@ pub async fn resume_k_thread() { pub fn routine() { println!("Routine executed"); crate::syscalls::syscall_routine(crate::syscalls::EXIT_ID); // Call exit + println!("SHOULD NEVER BE DISPLAYED"); } pub struct Thread { @@ -48,6 +49,7 @@ pub struct Thread { pub started: bool, pub rsp: u64, pub base_stack: u64, + pub is_blocked: bool, } impl Thread { @@ -60,6 +62,7 @@ impl Thread { started: false, rsp: stack_bottom + STACK_SIZE as u64, base_stack: stack_bottom, + is_blocked: false } } } diff --git a/src/syscalls/mod.rs b/src/syscalls/mod.rs index be2b42a..b6b5f11 100644 --- a/src/syscalls/mod.rs +++ b/src/syscalls/mod.rs @@ -1,4 +1,6 @@ +use crate::println; use crate::proc::thread::{resume_k_thread, RUNNING_THREAD}; +use crate::proc::scheduler::SCHEDULER; use crate::task::executor::EXECUTOR; use crate::task::Task; @@ -19,25 +21,47 @@ pub struct SyscallContext { thread_id: crate::proc::thread::ThreadId, } -pub fn syscall_dispatcher(context: SyscallContextT) -> Task { - match context.borrow().id { - EXIT_ID => Task::new(proc::exit(context.clone())), - _ => Task::new(bad_syscall()), +impl SyscallContext { + pub async fn run(&mut self) { + println!("Running async syscall runner"); + 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 { + println!("Running syscall"); let context: SyscallContextT = Arc::new(RefCell::new(SyscallContext { id: syscall_id, res: 0, thread_id: *RUNNING_THREAD.try_lock().unwrap(), })); + println!("Spawning async syscall runner"); EXECUTOR .try_lock() .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(); let res = context.borrow().res; diff --git a/src/syscalls/proc.rs b/src/syscalls/proc.rs index d8c8f3b..4148585 100644 --- a/src/syscalls/proc.rs +++ b/src/syscalls/proc.rs @@ -1,10 +1,10 @@ use crate::println; use crate::proc::scheduler::SCHEDULER; -use super::SyscallContextT; +use super::SyscallContext; -pub async fn exit(context: SyscallContextT) { - println!("Exiting thread"); +pub async fn exit(context: &SyscallContext) { + println!("Running exit(2)"); let mut scheduler = SCHEDULER.lock().await; - scheduler.exit(context.borrow().thread_id); + scheduler.exit(context.thread_id); }