diff --git a/src/libos/src/interrupt/mod.rs b/src/libos/src/interrupt/mod.rs index 7e3bd374..2f1fdfa4 100644 --- a/src/libos/src/interrupt/mod.rs +++ b/src/libos/src/interrupt/mod.rs @@ -38,8 +38,8 @@ pub fn broadcast_interrupts() -> Result { let should_interrupt_thread = |thread: &&ThreadRef| -> bool { // TODO: check Thread::sig_mask to reduce false positives thread.process().is_forced_to_exit() - || !thread.sig_queues().lock().unwrap().empty() - || !thread.process().sig_queues().lock().unwrap().empty() + || !thread.sig_queues().read().unwrap().empty() + || !thread.process().sig_queues().read().unwrap().empty() }; let num_signaled_threads = crate::process::table::get_all_threads() diff --git a/src/libos/src/prelude.rs b/src/libos/src/prelude.rs index 69b5b139..42f207f5 100644 --- a/src/libos/src/prelude.rs +++ b/src/libos/src/prelude.rs @@ -17,6 +17,7 @@ pub use crate::error::Result; pub use crate::error::*; pub use crate::fs::{File, FileDesc, FileRef}; pub use crate::process::{pid_t, uid_t}; +pub use crate::util::sync::RwLock; macro_rules! debug_trace { () => { diff --git a/src/libos/src/process/do_exit.rs b/src/libos/src/process/do_exit.rs index 2bebbc38..34c0c22c 100644 --- a/src/libos/src/process/do_exit.rs +++ b/src/libos/src/process/do_exit.rs @@ -130,6 +130,6 @@ fn exit_process(thread: &ThreadRef, term_status: TermStatus) { fn send_sigchld_to(parent: &Arc) { let signal = Box::new(KernelSignal::new(SigNum::from(SIGCHLD))); - let mut sig_queues = parent.sig_queues().lock().unwrap(); + let mut sig_queues = parent.sig_queues().write().unwrap(); sig_queues.enqueue(signal); } diff --git a/src/libos/src/process/process/builder.rs b/src/libos/src/process/process/builder.rs index 2dc446d4..23ff162a 100644 --- a/src/libos/src/process/process/builder.rs +++ b/src/libos/src/process/process/builder.rs @@ -100,7 +100,7 @@ impl ProcessBuilder { let parent = self.parent.take().map(|parent| SgxRwLock::new(parent)); let inner = SgxMutex::new(ProcessInner::new()); let sig_dispositions = SgxRwLock::new(SigDispositions::new()); - let sig_queues = SgxMutex::new(SigQueues::new()); + let sig_queues = RwLock::new(SigQueues::new()); let forced_exit_status = ForcedExitStatus::new(); Arc::new(Process { pid, diff --git a/src/libos/src/process/process/mod.rs b/src/libos/src/process/process/mod.rs index 64ffab2d..46bf94a1 100644 --- a/src/libos/src/process/process/mod.rs +++ b/src/libos/src/process/process/mod.rs @@ -20,7 +20,7 @@ pub struct Process { inner: SgxMutex, // Signal sig_dispositions: SgxRwLock, - sig_queues: SgxMutex, + sig_queues: RwLock, forced_exit_status: ForcedExitStatus, } @@ -100,7 +100,7 @@ impl Process { } /// Get the signal queues for process-directed signals. - pub fn sig_queues(&self) -> &SgxMutex { + pub fn sig_queues(&self) -> &RwLock { &self.sig_queues } diff --git a/src/libos/src/process/thread/builder.rs b/src/libos/src/process/thread/builder.rs index 6cea5863..a10ddc29 100644 --- a/src/libos/src/process/thread/builder.rs +++ b/src/libos/src/process/thread/builder.rs @@ -107,7 +107,7 @@ impl ThreadBuilder { let sched = self.sched.unwrap_or_default(); let rlimits = self.rlimits.unwrap_or_default(); let name = SgxRwLock::new(self.name.unwrap_or_default()); - let sig_queues = SgxMutex::new(SigQueues::new()); + let sig_queues = RwLock::new(SigQueues::new()); let sig_mask = SgxRwLock::new(SigSet::new_empty()); let sig_tmp_mask = SgxRwLock::new(SigSet::new_empty()); let sig_stack = SgxMutex::new(None); diff --git a/src/libos/src/process/thread/mod.rs b/src/libos/src/process/thread/mod.rs index b613b74b..ee79029a 100644 --- a/src/libos/src/process/thread/mod.rs +++ b/src/libos/src/process/thread/mod.rs @@ -36,7 +36,7 @@ pub struct Thread { sched: SchedAgentRef, rlimits: ResourceLimitsRef, // Signal - sig_queues: SgxMutex, + sig_queues: RwLock, sig_mask: SgxRwLock, sig_tmp_mask: SgxRwLock, sig_stack: SgxMutex>, @@ -81,7 +81,7 @@ impl Thread { } /// Get the signal queues for thread-directed signals. - pub fn sig_queues(&self) -> &SgxMutex { + pub fn sig_queues(&self) -> &RwLock { &self.sig_queues } diff --git a/src/libos/src/signal/do_kill.rs b/src/libos/src/signal/do_kill.rs index 3b7b0c4e..39cbdf5a 100644 --- a/src/libos/src/signal/do_kill.rs +++ b/src/libos/src/signal/do_kill.rs @@ -16,7 +16,7 @@ pub fn do_kill(filter: ProcessFilter, signum: SigNum) -> Result<()> { } let signal = Box::new(UserSignal::new(signum, UserSignalKind::Kill, pid, uid)); - let mut sig_queues = process.sig_queues().lock().unwrap(); + let mut sig_queues = process.sig_queues().write().unwrap(); sig_queues.enqueue(signal); } Ok(()) @@ -42,7 +42,7 @@ pub fn do_kill_from_outside_enclave(filter: ProcessFilter, signum: SigNum) -> Re continue; } - let mut sig_queues = process.sig_queues().lock().unwrap(); + let mut sig_queues = process.sig_queues().write().unwrap(); sig_queues.enqueue(signal.clone()); } Ok(()) @@ -97,7 +97,7 @@ pub fn do_tgkill(pid: Option, tid: pid_t, signum: SigNum) -> Result<()> { src_uid, )) }; - let mut sig_queues = thread.sig_queues().lock().unwrap(); + let mut sig_queues = thread.sig_queues().write().unwrap(); sig_queues.enqueue(signal); Ok(()) } diff --git a/src/libos/src/signal/do_sigpending.rs b/src/libos/src/signal/do_sigpending.rs index e82a1d4a..843935f5 100644 --- a/src/libos/src/signal/do_sigpending.rs +++ b/src/libos/src/signal/do_sigpending.rs @@ -6,8 +6,8 @@ pub fn do_sigpending() -> Result { let thread = current!(); let process = thread.process(); - let pending = (thread.sig_queues().lock().unwrap().pending() - | process.sig_queues().lock().unwrap().pending()) + let pending = (thread.sig_queues().read().unwrap().pending() + | process.sig_queues().read().unwrap().pending()) & *thread.sig_mask().read().unwrap(); Ok(pending) } diff --git a/src/libos/src/signal/do_sigreturn.rs b/src/libos/src/signal/do_sigreturn.rs index 3f0ece3d..6a0118d2 100644 --- a/src/libos/src/signal/do_sigreturn.rs +++ b/src/libos/src/signal/do_sigreturn.rs @@ -66,12 +66,23 @@ pub fn deliver_signal(cpu_context: &mut CpuContext) { fn do_deliver_signal(thread: &ThreadRef, process: &ProcessRef, cpu_context: &mut CpuContext) { loop { - // Dequeue a signal, respecting the signal mask and tmp mask - let sig_mask = *thread.sig_mask().read().unwrap() | *thread.sig_tmp_mask().read().unwrap(); + if process.sig_queues().read().unwrap().empty() + && thread.sig_queues().read().unwrap().empty() + { + return; + } + let signal = { - #[rustfmt::skip] - let signal_opt = process.sig_queues().lock().unwrap().dequeue(&sig_mask) - .or_else(|| thread.sig_queues().lock().unwrap().dequeue(&sig_mask)); + // Dequeue a signal, respecting the signal mask and tmp mask + let sig_mask = + *thread.sig_mask().read().unwrap() | *thread.sig_tmp_mask().read().unwrap(); + + let signal_opt = process + .sig_queues() + .write() + .unwrap() + .dequeue(&sig_mask) + .or_else(|| thread.sig_queues().write().unwrap().dequeue(&sig_mask)); if signal_opt.is_none() { return; } diff --git a/src/libos/src/signal/sig_queues.rs b/src/libos/src/signal/sig_queues.rs index 5422b42f..eb9c73be 100644 --- a/src/libos/src/signal/sig_queues.rs +++ b/src/libos/src/signal/sig_queues.rs @@ -7,7 +7,6 @@ use crate::prelude::*; pub struct SigQueues { count: usize, - has_kill: bool, std_queues: Vec>>, rt_queues: Vec>>, } @@ -15,12 +14,10 @@ pub struct SigQueues { impl SigQueues { pub fn new() -> Self { let count = 0; - let has_kill = false; let std_queues = (0..COUNT_STD_SIGS).map(|_| None).collect(); let rt_queues = (0..COUNT_RT_SIGS).map(|_| Default::default()).collect(); SigQueues { count, - has_kill, std_queues, rt_queues, }