Apply RwLock to the sig_queues of Process and Thread
The new RwLock has better performance than SgxMutex and SgxRwLock.
This commit is contained in:
parent
83637d7938
commit
4f965fd8db
@ -38,8 +38,8 @@ pub fn broadcast_interrupts() -> Result<usize> {
|
|||||||
let should_interrupt_thread = |thread: &&ThreadRef| -> bool {
|
let should_interrupt_thread = |thread: &&ThreadRef| -> bool {
|
||||||
// TODO: check Thread::sig_mask to reduce false positives
|
// TODO: check Thread::sig_mask to reduce false positives
|
||||||
thread.process().is_forced_to_exit()
|
thread.process().is_forced_to_exit()
|
||||||
|| !thread.sig_queues().lock().unwrap().empty()
|
|| !thread.sig_queues().read().unwrap().empty()
|
||||||
|| !thread.process().sig_queues().lock().unwrap().empty()
|
|| !thread.process().sig_queues().read().unwrap().empty()
|
||||||
};
|
};
|
||||||
|
|
||||||
let num_signaled_threads = crate::process::table::get_all_threads()
|
let num_signaled_threads = crate::process::table::get_all_threads()
|
||||||
|
@ -17,6 +17,7 @@ pub use crate::error::Result;
|
|||||||
pub use crate::error::*;
|
pub use crate::error::*;
|
||||||
pub use crate::fs::{File, FileDesc, FileRef};
|
pub use crate::fs::{File, FileDesc, FileRef};
|
||||||
pub use crate::process::{pid_t, uid_t};
|
pub use crate::process::{pid_t, uid_t};
|
||||||
|
pub use crate::util::sync::RwLock;
|
||||||
|
|
||||||
macro_rules! debug_trace {
|
macro_rules! debug_trace {
|
||||||
() => {
|
() => {
|
||||||
|
@ -130,6 +130,6 @@ fn exit_process(thread: &ThreadRef, term_status: TermStatus) {
|
|||||||
|
|
||||||
fn send_sigchld_to(parent: &Arc<Process>) {
|
fn send_sigchld_to(parent: &Arc<Process>) {
|
||||||
let signal = Box::new(KernelSignal::new(SigNum::from(SIGCHLD)));
|
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);
|
sig_queues.enqueue(signal);
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ impl ProcessBuilder {
|
|||||||
let parent = self.parent.take().map(|parent| SgxRwLock::new(parent));
|
let parent = self.parent.take().map(|parent| SgxRwLock::new(parent));
|
||||||
let inner = SgxMutex::new(ProcessInner::new());
|
let inner = SgxMutex::new(ProcessInner::new());
|
||||||
let sig_dispositions = SgxRwLock::new(SigDispositions::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();
|
let forced_exit_status = ForcedExitStatus::new();
|
||||||
Arc::new(Process {
|
Arc::new(Process {
|
||||||
pid,
|
pid,
|
||||||
|
@ -20,7 +20,7 @@ pub struct Process {
|
|||||||
inner: SgxMutex<ProcessInner>,
|
inner: SgxMutex<ProcessInner>,
|
||||||
// Signal
|
// Signal
|
||||||
sig_dispositions: SgxRwLock<SigDispositions>,
|
sig_dispositions: SgxRwLock<SigDispositions>,
|
||||||
sig_queues: SgxMutex<SigQueues>,
|
sig_queues: RwLock<SigQueues>,
|
||||||
forced_exit_status: ForcedExitStatus,
|
forced_exit_status: ForcedExitStatus,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ impl Process {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the signal queues for process-directed signals.
|
/// Get the signal queues for process-directed signals.
|
||||||
pub fn sig_queues(&self) -> &SgxMutex<SigQueues> {
|
pub fn sig_queues(&self) -> &RwLock<SigQueues> {
|
||||||
&self.sig_queues
|
&self.sig_queues
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ impl ThreadBuilder {
|
|||||||
let sched = self.sched.unwrap_or_default();
|
let sched = self.sched.unwrap_or_default();
|
||||||
let rlimits = self.rlimits.unwrap_or_default();
|
let rlimits = self.rlimits.unwrap_or_default();
|
||||||
let name = SgxRwLock::new(self.name.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_mask = SgxRwLock::new(SigSet::new_empty());
|
||||||
let sig_tmp_mask = SgxRwLock::new(SigSet::new_empty());
|
let sig_tmp_mask = SgxRwLock::new(SigSet::new_empty());
|
||||||
let sig_stack = SgxMutex::new(None);
|
let sig_stack = SgxMutex::new(None);
|
||||||
|
@ -36,7 +36,7 @@ pub struct Thread {
|
|||||||
sched: SchedAgentRef,
|
sched: SchedAgentRef,
|
||||||
rlimits: ResourceLimitsRef,
|
rlimits: ResourceLimitsRef,
|
||||||
// Signal
|
// Signal
|
||||||
sig_queues: SgxMutex<SigQueues>,
|
sig_queues: RwLock<SigQueues>,
|
||||||
sig_mask: SgxRwLock<SigSet>,
|
sig_mask: SgxRwLock<SigSet>,
|
||||||
sig_tmp_mask: SgxRwLock<SigSet>,
|
sig_tmp_mask: SgxRwLock<SigSet>,
|
||||||
sig_stack: SgxMutex<Option<SigStack>>,
|
sig_stack: SgxMutex<Option<SigStack>>,
|
||||||
@ -81,7 +81,7 @@ impl Thread {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the signal queues for thread-directed signals.
|
/// Get the signal queues for thread-directed signals.
|
||||||
pub fn sig_queues(&self) -> &SgxMutex<SigQueues> {
|
pub fn sig_queues(&self) -> &RwLock<SigQueues> {
|
||||||
&self.sig_queues
|
&self.sig_queues
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 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);
|
sig_queues.enqueue(signal);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -42,7 +42,7 @@ pub fn do_kill_from_outside_enclave(filter: ProcessFilter, signum: SigNum) -> Re
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut sig_queues = process.sig_queues().lock().unwrap();
|
let mut sig_queues = process.sig_queues().write().unwrap();
|
||||||
sig_queues.enqueue(signal.clone());
|
sig_queues.enqueue(signal.clone());
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -97,7 +97,7 @@ pub fn do_tgkill(pid: Option<pid_t>, tid: pid_t, signum: SigNum) -> Result<()> {
|
|||||||
src_uid,
|
src_uid,
|
||||||
))
|
))
|
||||||
};
|
};
|
||||||
let mut sig_queues = thread.sig_queues().lock().unwrap();
|
let mut sig_queues = thread.sig_queues().write().unwrap();
|
||||||
sig_queues.enqueue(signal);
|
sig_queues.enqueue(signal);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,8 @@ pub fn do_sigpending() -> Result<SigSet> {
|
|||||||
|
|
||||||
let thread = current!();
|
let thread = current!();
|
||||||
let process = thread.process();
|
let process = thread.process();
|
||||||
let pending = (thread.sig_queues().lock().unwrap().pending()
|
let pending = (thread.sig_queues().read().unwrap().pending()
|
||||||
| process.sig_queues().lock().unwrap().pending())
|
| process.sig_queues().read().unwrap().pending())
|
||||||
& *thread.sig_mask().read().unwrap();
|
& *thread.sig_mask().read().unwrap();
|
||||||
Ok(pending)
|
Ok(pending)
|
||||||
}
|
}
|
||||||
|
@ -66,12 +66,23 @@ pub fn deliver_signal(cpu_context: &mut CpuContext) {
|
|||||||
|
|
||||||
fn do_deliver_signal(thread: &ThreadRef, process: &ProcessRef, cpu_context: &mut CpuContext) {
|
fn do_deliver_signal(thread: &ThreadRef, process: &ProcessRef, cpu_context: &mut CpuContext) {
|
||||||
loop {
|
loop {
|
||||||
// Dequeue a signal, respecting the signal mask and tmp mask
|
if process.sig_queues().read().unwrap().empty()
|
||||||
let sig_mask = *thread.sig_mask().read().unwrap() | *thread.sig_tmp_mask().read().unwrap();
|
&& thread.sig_queues().read().unwrap().empty()
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let signal = {
|
let signal = {
|
||||||
#[rustfmt::skip]
|
// Dequeue a signal, respecting the signal mask and tmp mask
|
||||||
let signal_opt = process.sig_queues().lock().unwrap().dequeue(&sig_mask)
|
let sig_mask =
|
||||||
.or_else(|| thread.sig_queues().lock().unwrap().dequeue(&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() {
|
if signal_opt.is_none() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ use crate::prelude::*;
|
|||||||
|
|
||||||
pub struct SigQueues {
|
pub struct SigQueues {
|
||||||
count: usize,
|
count: usize,
|
||||||
has_kill: bool,
|
|
||||||
std_queues: Vec<Option<Box<dyn Signal>>>,
|
std_queues: Vec<Option<Box<dyn Signal>>>,
|
||||||
rt_queues: Vec<VecDeque<Box<dyn Signal>>>,
|
rt_queues: Vec<VecDeque<Box<dyn Signal>>>,
|
||||||
}
|
}
|
||||||
@ -15,12 +14,10 @@ pub struct SigQueues {
|
|||||||
impl SigQueues {
|
impl SigQueues {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let count = 0;
|
let count = 0;
|
||||||
let has_kill = false;
|
|
||||||
let std_queues = (0..COUNT_STD_SIGS).map(|_| None).collect();
|
let std_queues = (0..COUNT_STD_SIGS).map(|_| None).collect();
|
||||||
let rt_queues = (0..COUNT_RT_SIGS).map(|_| Default::default()).collect();
|
let rt_queues = (0..COUNT_RT_SIGS).map(|_| Default::default()).collect();
|
||||||
SigQueues {
|
SigQueues {
|
||||||
count,
|
count,
|
||||||
has_kill,
|
|
||||||
std_queues,
|
std_queues,
|
||||||
rt_queues,
|
rt_queues,
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user