From 68609a0f7cbcfd9b06bab83658008abaf64f23c6 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Mon, 29 Jun 2020 11:09:21 +0800 Subject: [PATCH] Add yield to avoid starvation --- kernel/src/process/thread.rs | 28 ++++++++++++++++++++++++++++ kernel/src/syscall/signal.rs | 16 ++++++++++++---- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/kernel/src/process/thread.rs b/kernel/src/process/thread.rs index bcf402fc..8c512d5b 100644 --- a/kernel/src/process/thread.rs +++ b/kernel/src/process/thread.rs @@ -511,7 +511,10 @@ pub fn spawn(thread: Arc) { thread.end_running(cx); if exit { + info!("thread {} stopped", thread.tid); break; + } else { + yield_now().await; } } }; @@ -556,3 +559,28 @@ impl Future for PageTableSwitchWrapper { res } } + +/// Yields execution back to the async runtime. +pub fn yield_now() -> impl Future { + YieldFuture::default() +} + +#[must_use = "yield_now does nothing unless polled/`await`-ed"] +#[derive(Default)] +struct YieldFuture { + flag: bool, +} + +impl Future for YieldFuture { + type Output = (); + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll { + if self.flag { + Poll::Ready(()) + } else { + self.flag = true; + cx.waker().clone().wake(); + Poll::Pending + } + } +} diff --git a/kernel/src/syscall/signal.rs b/kernel/src/syscall/signal.rs index daac7297..bf40eca4 100644 --- a/kernel/src/syscall/signal.rs +++ b/kernel/src/syscall/signal.rs @@ -110,15 +110,23 @@ impl Syscall<'_> { } if !set.is_null() { let set = set.read()?; - info!("rt_sigprocmask: set: {:?}", set); const BLOCK: usize = 0; const UNBLOCK: usize = 1; const SETMASK: usize = 2; let mut inner = self.thread.inner.lock(); match how { - BLOCK => inner.sig_mask.add_set(&set), - UNBLOCK => inner.sig_mask.remove_set(&set), - SETMASK => inner.sig_mask = set, + BLOCK => { + info!("rt_sigprocmask: block: {:x?}", set); + inner.sig_mask.add_set(&set); + } + UNBLOCK => { + info!("rt_sigprocmask: unblock: {:x?}", set); + inner.sig_mask.remove_set(&set) + } + SETMASK => { + info!("rt_sigprocmask: set: {:x?}", set); + inner.sig_mask = set; + } _ => return Err(EINVAL), } }