diff --git a/kernel/aster-nix/src/process/clone.rs b/kernel/aster-nix/src/process/clone.rs index cf7a93e48..62de1bf53 100644 --- a/kernel/aster-nix/src/process/clone.rs +++ b/kernel/aster-nix/src/process/clone.rs @@ -175,8 +175,10 @@ fn clone_child_thread(parent_context: &UserContext, clone_args: CloneArgs) -> Re let sig_mask = { let current_thread = current_thread!(); let current_posix_thread = current_thread.as_posix_thread().unwrap(); - let sigmask = current_posix_thread.sig_mask().lock(); - *sigmask + current_posix_thread + .sig_mask() + .load(Ordering::Relaxed) + .into() }; let child_tid = allocate_tid(); @@ -258,8 +260,7 @@ fn clone_child_process( let child_sig_mask = { let current_thread = current_thread!(); let posix_thread = current_thread.as_posix_thread().unwrap(); - let sigmask = posix_thread.sig_mask().lock(); - *sigmask + posix_thread.sig_mask().load(Ordering::Relaxed).into() }; // inherit parent's nice value diff --git a/kernel/aster-nix/src/process/posix_thread/builder.rs b/kernel/aster-nix/src/process/posix_thread/builder.rs index cbce48e35..54002ab1c 100644 --- a/kernel/aster-nix/src/process/posix_thread/builder.rs +++ b/kernel/aster-nix/src/process/posix_thread/builder.rs @@ -9,7 +9,7 @@ use crate::{ prelude::*, process::{ posix_thread::name::ThreadName, - signal::{sig_mask::SigMask, sig_queues::SigQueues}, + signal::{sig_mask::AtomicSigMask, sig_queues::SigQueues}, Credentials, Process, }, thread::{status::ThreadStatus, task, thread_table, Thread, Tid}, @@ -28,7 +28,7 @@ pub struct PosixThreadBuilder { thread_name: Option, set_child_tid: Vaddr, clear_child_tid: Vaddr, - sig_mask: SigMask, + sig_mask: AtomicSigMask, sig_queues: SigQueues, } @@ -42,7 +42,7 @@ impl PosixThreadBuilder { thread_name: None, set_child_tid: 0, clear_child_tid: 0, - sig_mask: SigMask::new_empty(), + sig_mask: AtomicSigMask::new_empty(), sig_queues: SigQueues::new(), } } @@ -67,7 +67,7 @@ impl PosixThreadBuilder { self } - pub fn sig_mask(mut self, sig_mask: SigMask) -> Self { + pub fn sig_mask(mut self, sig_mask: AtomicSigMask) -> Self { self.sig_mask = sig_mask; self } @@ -99,7 +99,7 @@ impl PosixThreadBuilder { set_child_tid: Mutex::new(set_child_tid), clear_child_tid: Mutex::new(clear_child_tid), credentials, - sig_mask: Mutex::new(sig_mask), + sig_mask, sig_queues, sig_context: Mutex::new(None), sig_stack: Mutex::new(None), diff --git a/kernel/aster-nix/src/process/posix_thread/mod.rs b/kernel/aster-nix/src/process/posix_thread/mod.rs index 4af180e55..32b52e299 100644 --- a/kernel/aster-nix/src/process/posix_thread/mod.rs +++ b/kernel/aster-nix/src/process/posix_thread/mod.rs @@ -2,12 +2,14 @@ #![allow(dead_code)] +use core::sync::atomic::Ordering; + use aster_rights::{ReadOp, WriteOp}; use super::{ kill::SignalSenderIds, signal::{ - sig_mask::{SigMask, SigSet}, + sig_mask::{AtomicSigMask, SigMask, SigSet}, sig_num::SigNum, sig_queues::SigQueues, signals::Signal, @@ -55,7 +57,7 @@ pub struct PosixThread { // Signal /// Blocked signals - sig_mask: Mutex, + sig_mask: AtomicSigMask, /// Thread-directed sigqueue sig_queues: SigQueues, /// Signal handler ucontext address @@ -90,7 +92,12 @@ impl PosixThread { &self.clear_child_tid } - pub fn sig_mask(&self) -> &Mutex { + /// Get the reference to the signal mask of the thread. + /// + /// Note that while this function offers mutable access to the signal mask, + /// it is not sound for callers other than the current thread to modify the + /// signal mask. They may only read the signal mask. + pub fn sig_mask(&self) -> &AtomicSigMask { &self.sig_mask } @@ -101,14 +108,13 @@ impl PosixThread { /// Returns whether the thread has some pending signals /// that are not blocked. pub fn has_pending(&self) -> bool { - let blocked = *self.sig_mask().lock(); + let blocked = self.sig_mask().load(Ordering::Relaxed); self.sig_queues.has_pending(blocked) } /// Returns whether the signal is blocked by the thread. pub(in crate::process) fn has_signal_blocked(&self, signal: &dyn Signal) -> bool { - let mask = self.sig_mask.lock(); - mask.contains(signal.num()) + self.sig_mask.contains(signal.num(), Ordering::Relaxed) } /// Checks whether the signal can be delivered to the thread. diff --git a/kernel/aster-nix/src/process/process/mod.rs b/kernel/aster-nix/src/process/process/mod.rs index 54b594287..362d52df9 100644 --- a/kernel/aster-nix/src/process/process/mod.rs +++ b/kernel/aster-nix/src/process/process/mod.rs @@ -9,7 +9,6 @@ use super::{ signal::{ constants::SIGCHLD, sig_disposition::SigDispositions, - sig_mask::SigMask, sig_num::{AtomicSigNum, SigNum}, signals::Signal, Pauser, @@ -120,12 +119,9 @@ impl Process { nice: Nice, sig_dispositions: Arc>, ) -> Arc { - let children_pauser = { - // SIGCHID does not interrupt pauser. Child process will - // resume paused parent when doing exit. - let sigmask = SigMask::from(SIGCHLD); - Pauser::new_with_mask(sigmask) - }; + // SIGCHID does not interrupt pauser. Child process will + // resume paused parent when doing exit. + let children_pauser = Pauser::new_with_mask(SIGCHLD.into()); let prof_clock = ProfClock::new(); diff --git a/kernel/aster-nix/src/process/signal/mod.rs b/kernel/aster-nix/src/process/signal/mod.rs index 400ba3632..a53dcf201 100644 --- a/kernel/aster-nix/src/process/signal/mod.rs +++ b/kernel/aster-nix/src/process/signal/mod.rs @@ -49,7 +49,7 @@ pub fn handle_pending_signal( // We first deal with signal in current thread, then signal in current process. let posix_thread = current_thread.as_posix_thread().unwrap(); let signal = { - let sig_mask = *posix_thread.sig_mask().lock(); + let sig_mask = posix_thread.sig_mask().load(Ordering::Relaxed); if let Some(signal) = posix_thread.dequeue_signal(&sig_mask) { signal } else { @@ -136,13 +136,15 @@ pub fn handle_user_signal( } if !flags.contains(SigActionFlags::SA_NODEFER) { // add current signal to mask - let current_mask = SigMask::from(sig_num); - mask.block(current_mask.as_u64()); + mask += sig_num; } let current_thread = current_thread!(); let posix_thread = current_thread.as_posix_thread().unwrap(); // block signals in sigmask when running signal handler - posix_thread.sig_mask().lock().block(mask.as_u64()); + let old_mask = posix_thread.sig_mask().load(Ordering::Relaxed); + posix_thread + .sig_mask() + .store(old_mask + mask, Ordering::Relaxed); // Set up signal stack. let mut stack_pointer = if let Some(sp) = use_alternate_signal_stack(posix_thread) { @@ -163,7 +165,7 @@ pub fn handle_user_signal( // 2. write ucontext_t. stack_pointer = alloc_aligned_in_user_stack(stack_pointer, mem::size_of::(), 16)?; let mut ucontext = ucontext_t { - uc_sigmask: mask.as_u64(), + uc_sigmask: mask.into(), ..Default::default() }; ucontext diff --git a/kernel/aster-nix/src/process/signal/pauser.rs b/kernel/aster-nix/src/process/signal/pauser.rs index 015f1e904..c200dc465 100644 --- a/kernel/aster-nix/src/process/signal/pauser.rs +++ b/kernel/aster-nix/src/process/signal/pauser.rs @@ -185,13 +185,9 @@ impl<'a> SigObserverRegistrar<'a> { // Block `sig_mask`. let (old_mask, filter) = { - let mut locked_mask = thread.sig_mask().lock(); - - let old_mask = *locked_mask; - let new_mask = { - locked_mask.block(sig_mask.as_u64()); - *locked_mask - }; + let old_mask = thread.sig_mask().load(Ordering::Relaxed); + let new_mask = old_mask + sig_mask; + thread.sig_mask().store(new_mask, Ordering::Relaxed); (old_mask, SigEventsFilter::new(new_mask)) }; @@ -234,7 +230,7 @@ impl<'a> Drop for SigObserverRegistrar<'a> { // Restore the state, assuming no one else can modify the current thread's signal mask // during the pause. thread.unregiser_sigqueue_observer(&(Arc::downgrade(observer) as _)); - thread.sig_mask().lock().set(old_mask.as_u64()); + thread.sig_mask().store(*old_mask, Ordering::Relaxed); } } diff --git a/kernel/aster-nix/src/process/signal/sig_action.rs b/kernel/aster-nix/src/process/signal/sig_action.rs index 6301cb386..52293ce41 100644 --- a/kernel/aster-nix/src/process/signal/sig_action.rs +++ b/kernel/aster-nix/src/process/signal/sig_action.rs @@ -28,7 +28,7 @@ impl TryFrom for SigAction { SIG_IGN => SigAction::Ign, _ => { let flags = SigActionFlags::from_bits_truncate(input.flags); - let mask = SigMask::from(input.mask); + let mask = input.mask.into(); SigAction::User { handler_addr: input.handler_ptr, flags, @@ -65,7 +65,7 @@ impl SigAction { handler_ptr: *handler_addr, flags: flags.as_u32(), restorer_ptr: *restorer_addr, - mask: mask.as_u64(), + mask: (*mask).into(), }, } } diff --git a/kernel/aster-nix/src/process/signal/sig_mask.rs b/kernel/aster-nix/src/process/signal/sig_mask.rs index b82ebc0f7..f3b84be6f 100644 --- a/kernel/aster-nix/src/process/signal/sig_mask.rs +++ b/kernel/aster-nix/src/process/signal/sig_mask.rs @@ -1,84 +1,220 @@ // SPDX-License-Identifier: MPL-2.0 +//! Signal sets and atomic masks. +//! +//! A signal set is a bit-set of signals. A signal mask is a set of signals +//! that are blocked from delivery to a thread. An atomic signal mask +//! implementation is provided for shared access to signal masks. + +use core::{ + fmt::LowerHex, + ops, + sync::atomic::{AtomicU64, Ordering}, +}; + use super::{constants::MIN_STD_SIG_NUM, sig_num::SigNum}; use crate::prelude::*; /// A signal mask. +/// +/// This is an alias to the [`SigSet`]. All the signal in the set are blocked +/// from the delivery to a thread. pub type SigMask = SigSet; +/// A bit-set of signals. +/// +/// Because that all the signal numbers are in the range of 1 to 64, casting +/// a signal set from `u64` to `SigSet` will always succeed. #[derive(Debug, Copy, Clone, Default, PartialEq, Eq, Pod)] #[repr(C)] pub struct SigSet { bits: u64, } -impl From for SigMask { +impl From for SigSet { + fn from(signum: SigNum) -> Self { + let idx = signum.as_u8() - MIN_STD_SIG_NUM; + Self { bits: 1_u64 << idx } + } +} + +impl From for SigSet { fn from(bits: u64) -> Self { - SigMask { bits } + SigSet { bits } } } -impl From for SigMask { - fn from(sig_num: SigNum) -> Self { - let idx = SigMask::num_to_idx(sig_num); - let bits = 1u64 << idx; - SigMask { bits } +impl From for u64 { + fn from(set: SigSet) -> u64 { + set.bits } } -impl SigMask { +impl> ops::BitAnd for SigSet { + type Output = Self; + + fn bitand(self, rhs: T) -> Self { + SigSet { + bits: self.bits & rhs.into().bits, + } + } +} + +impl> ops::BitAndAssign for SigSet { + fn bitand_assign(&mut self, rhs: T) { + self.bits &= rhs.into().bits; + } +} + +impl> ops::BitOr for SigSet { + type Output = Self; + + fn bitor(self, rhs: T) -> Self { + SigSet { + bits: self.bits | rhs.into().bits, + } + } +} + +impl> ops::BitOrAssign for SigSet { + fn bitor_assign(&mut self, rhs: T) { + self.bits |= rhs.into().bits; + } +} + +#[allow(clippy::suspicious_arithmetic_impl)] +impl> ops::Add for SigSet { + type Output = Self; + + fn add(self, rhs: T) -> Self { + SigSet { + bits: self.bits | rhs.into().bits, + } + } +} + +#[allow(clippy::suspicious_op_assign_impl)] +impl> ops::AddAssign for SigSet { + fn add_assign(&mut self, rhs: T) { + self.bits |= rhs.into().bits; + } +} + +impl> ops::Sub for SigSet { + type Output = Self; + + fn sub(self, rhs: T) -> Self { + SigSet { + bits: self.bits & !rhs.into().bits, + } + } +} + +impl> ops::SubAssign for SigSet { + fn sub_assign(&mut self, rhs: T) { + self.bits &= !rhs.into().bits; + } +} + +impl SigSet { pub fn new_empty() -> Self { - SigMask::from(0u64) + SigSet { bits: 0 } } pub fn new_full() -> Self { - SigMask::from(!0u64) + SigSet { bits: !0 } } - pub const fn as_u64(&self) -> u64 { - self.bits - } - - pub const fn empty(&self) -> bool { + pub const fn is_empty(&self) -> bool { self.bits == 0 } - pub const fn full(&self) -> bool { + pub const fn is_full(&self) -> bool { self.bits == !0 } - pub fn block(&mut self, block_sets: u64) { - self.bits |= block_sets; - } - - pub fn unblock(&mut self, unblock_sets: u64) { - self.bits &= !unblock_sets; - } - - pub fn set(&mut self, new_set: u64) { - self.bits = new_set; - } - pub fn count(&self) -> usize { self.bits.count_ones() as usize } - pub fn contains(&self, signum: SigNum) -> bool { - let idx = Self::num_to_idx(signum); - (self.bits & (1_u64 << idx)) != 0 - } - - fn num_to_idx(num: SigNum) -> usize { - (num.as_u8() - MIN_STD_SIG_NUM) as usize - } - - pub fn remove_signal(&mut self, signum: SigNum) { - let idx = Self::num_to_idx(signum); - self.bits &= !(1_u64 << idx); - } - - pub fn add_signal(&mut self, signum: SigNum) { - let idx = Self::num_to_idx(signum); - self.bits |= 1_u64 << idx; + pub fn contains(&self, set: impl Into) -> bool { + let set = set.into(); + self.bits & set.bits == set.bits + } +} + +// This is to allow hexadecimally formatting a `SigSet` when debug printing it. +impl LowerHex for SigSet { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + LowerHex::fmt(&self.bits, f) // delegate to u64's implementation + } +} + +/// An atomic signal mask. +/// +/// This is an alias to the [`AtomicSigSet`]. All the signal in the set are +/// blocked from the delivery to a thread. +/// +/// [`Relaxed`]: core::sync::atomic::Ordering::Relaxed +pub type AtomicSigMask = AtomicSigSet; + +/// An atomic signal set. +pub struct AtomicSigSet(AtomicU64); + +impl From for AtomicSigSet { + fn from(set: SigSet) -> Self { + AtomicSigSet(AtomicU64::new(set.bits)) + } +} + +impl AtomicSigSet { + pub fn new_empty() -> Self { + AtomicSigSet(AtomicU64::new(0)) + } + + pub fn new_full() -> Self { + AtomicSigSet(AtomicU64::new(!0)) + } + + pub fn load(&self, ordering: Ordering) -> SigSet { + SigSet { + bits: self.0.load(ordering), + } + } + + pub fn store(&self, new_mask: impl Into, ordering: Ordering) { + self.0.store(new_mask.into().bits, ordering); + } + + pub fn contains(&self, signals: impl Into, ordering: Ordering) -> bool { + SigSet { + bits: self.0.load(ordering), + } + .contains(signals.into()) + } + + /// Applies an update to the signal set. + /// + /// This is the same as [`AtomicU64::fetch_update`], but the closure `f` + /// operates on a [`SigMask`] instead of a `u64`. + /// + /// It would be a bit slow since it would check if the value is written by + /// another thread while evaluating the closure `f`. If you are confident + /// that there's no such race, don't use this method. + pub fn fetch_update( + &self, + set_order: Ordering, + fetch_order: Ordering, + mut f: F, + ) -> core::result::Result + where + F: FnMut(SigMask) -> Option, + { + self.0 + .fetch_update(set_order, fetch_order, |bits| { + f(SigMask { bits }).map(|set| set.bits) + }) + .map(SigMask::from) + .map_err(SigMask::from) } } diff --git a/kernel/aster-nix/src/process/signal/sig_queues.rs b/kernel/aster-nix/src/process/signal/sig_queues.rs index d48dad44e..692c7c6dd 100644 --- a/kernel/aster-nix/src/process/signal/sig_queues.rs +++ b/kernel/aster-nix/src/process/signal/sig_queues.rs @@ -222,14 +222,14 @@ impl Queues { // Process standard signal queues for (idx, signal) in self.std_queues.iter().enumerate() { if signal.is_some() { - pending.add_signal(SigNum::from_u8(idx as u8 + MIN_STD_SIG_NUM)); + pending += SigNum::from_u8(idx as u8 + MIN_STD_SIG_NUM); } } // Process real-time signal queues for (idx, signals) in self.rt_queues.iter().enumerate() { if !signals.is_empty() { - pending.add_signal(SigNum::from_u8(idx as u8 + MIN_RT_SIG_NUM)); + pending += SigNum::from_u8(idx as u8 + MIN_RT_SIG_NUM); } } diff --git a/kernel/aster-nix/src/syscall/epoll.rs b/kernel/aster-nix/src/syscall/epoll.rs index 39868a9a8..f3fb8aca6 100644 --- a/kernel/aster-nix/src/syscall/epoll.rs +++ b/kernel/aster-nix/src/syscall/epoll.rs @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -use core::time::Duration; +use core::{sync::atomic::Ordering, time::Duration}; use super::SyscallReturn; use crate::{ @@ -11,7 +11,7 @@ use crate::{ utils::CreationFlags, }, prelude::*, - process::posix_thread::PosixThreadExt, + process::{posix_thread::PosixThreadExt, signal::sig_mask::SigMask}, util::{read_val_from_user, write_val_to_user}, }; @@ -148,32 +148,31 @@ pub fn sys_epoll_wait( Ok(SyscallReturn::Return(epoll_events.len() as _)) } -fn set_signal_mask(set_ptr: Vaddr) -> Result { - let new_set: Option = if set_ptr != 0 { - Some(read_val_from_user::(set_ptr)?) +fn set_signal_mask(set_ptr: Vaddr) -> Result { + let new_mask: Option = if set_ptr != 0 { + Some(read_val_from_user::(set_ptr)?.into()) } else { None }; let current_thread = current_thread!(); let posix_thread = current_thread.as_posix_thread().unwrap(); - let mut sig_mask = posix_thread.sig_mask().lock(); - let old_sig_mask_value = sig_mask.as_u64(); + let old_sig_mask_value = posix_thread.sig_mask().load(Ordering::Relaxed); - if let Some(new_set) = new_set { - sig_mask.set(new_set); + if let Some(new_mask) = new_mask { + posix_thread.sig_mask().store(new_mask, Ordering::Relaxed); } Ok(old_sig_mask_value) } -fn restore_signal_mask(sig_mask_val: u64) { +fn restore_signal_mask(sig_mask_val: SigMask) { let current_thread = current_thread!(); let posix_thread = current_thread.as_posix_thread().unwrap(); - let mut sig_mask = posix_thread.sig_mask().lock(); - - sig_mask.set(sig_mask_val); + posix_thread + .sig_mask() + .store(sig_mask_val, Ordering::Relaxed); } pub fn sys_epoll_pwait( diff --git a/kernel/aster-nix/src/syscall/rt_sigpending.rs b/kernel/aster-nix/src/syscall/rt_sigpending.rs index e19af003d..d6f2f929e 100644 --- a/kernel/aster-nix/src/syscall/rt_sigpending.rs +++ b/kernel/aster-nix/src/syscall/rt_sigpending.rs @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -#![allow(unused_variables)] +use core::sync::atomic::Ordering; use super::SyscallReturn; use crate::{prelude::*, process::posix_thread::PosixThreadExt, util::write_val_to_user}; @@ -13,20 +13,20 @@ pub fn sys_rt_sigpending(u_set_ptr: Vaddr, sigset_size: usize) -> Result Result<()> { +fn do_rt_sigpending(set_ptr: Vaddr) -> Result<()> { let current_thread = current_thread!(); let posix_thread = current_thread.as_posix_thread().unwrap(); let combined_signals = { - let sig_mask_value = posix_thread.sig_mask().lock().as_u64(); - let sig_pending_value = posix_thread.sig_pending().as_u64(); + let sig_mask_value = posix_thread.sig_mask().load(Ordering::Relaxed); + let sig_pending_value = posix_thread.sig_pending(); sig_mask_value & sig_pending_value }; - write_val_to_user(set_ptr, &combined_signals)?; + write_val_to_user(set_ptr, &u64::from(combined_signals))?; Ok(()) } diff --git a/kernel/aster-nix/src/syscall/rt_sigprocmask.rs b/kernel/aster-nix/src/syscall/rt_sigprocmask.rs index 45c723a70..81f429940 100644 --- a/kernel/aster-nix/src/syscall/rt_sigprocmask.rs +++ b/kernel/aster-nix/src/syscall/rt_sigprocmask.rs @@ -1,8 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -#![allow(unused_variables)] - -use ostd::mm::VmIo; +use core::sync::atomic::Ordering; use super::SyscallReturn; use crate::{ @@ -14,6 +12,7 @@ use crate::{ sig_mask::SigMask, }, }, + util::{read_val_from_user, write_val_to_user}, }; pub fn sys_rt_sigprocmask( @@ -30,42 +29,38 @@ pub fn sys_rt_sigprocmask( if sigset_size != 8 { error!("sigset size is not equal to 8"); } - do_rt_sigprocmask(mask_op, set_ptr, oldset_ptr, sigset_size).unwrap(); + do_rt_sigprocmask(mask_op, set_ptr, oldset_ptr).unwrap(); Ok(SyscallReturn::Return(0)) } -fn do_rt_sigprocmask( - mask_op: MaskOp, - set_ptr: Vaddr, - oldset_ptr: Vaddr, - sigset_size: usize, -) -> Result<()> { - let current = current!(); +fn do_rt_sigprocmask(mask_op: MaskOp, set_ptr: Vaddr, oldset_ptr: Vaddr) -> Result<()> { let current_thread = current_thread!(); let posix_thread = current_thread.as_posix_thread().unwrap(); - let root_vmar = current.root_vmar(); - let mut sig_mask = posix_thread.sig_mask().lock(); - let old_sig_mask_value = sig_mask.as_u64(); + + let old_sig_mask_value = posix_thread.sig_mask().load(Ordering::Relaxed); debug!("old sig mask value: 0x{:x}", old_sig_mask_value); if oldset_ptr != 0 { - root_vmar.write_val(oldset_ptr, &old_sig_mask_value)?; + write_val_to_user(oldset_ptr, &old_sig_mask_value)?; } + + let sig_mask_ref = posix_thread.sig_mask(); if set_ptr != 0 { - let new_set = root_vmar.read_val::(set_ptr)?; + let mut read_mask = read_val_from_user::(set_ptr)?; match mask_op { MaskOp::Block => { - let mut new_sig_mask = SigMask::from(new_set); // According to man pages, "it is not possible to block SIGKILL or SIGSTOP. // Attempts to do so are silently ignored." - new_sig_mask.remove_signal(SIGKILL); - new_sig_mask.remove_signal(SIGSTOP); - sig_mask.block(new_sig_mask.as_u64()); + read_mask -= SIGKILL; + read_mask -= SIGSTOP; + sig_mask_ref.store(old_sig_mask_value + read_mask, Ordering::Relaxed); } - MaskOp::Unblock => sig_mask.unblock(new_set), - MaskOp::SetMask => sig_mask.set(new_set), + MaskOp::Unblock => { + sig_mask_ref.store(old_sig_mask_value - read_mask, Ordering::Relaxed) + } + MaskOp::SetMask => sig_mask_ref.store(read_mask, Ordering::Relaxed), } } - debug!("new set = {:x?}", &sig_mask); + debug!("new set = {:x?}", sig_mask_ref.load(Ordering::Relaxed)); Ok(()) } diff --git a/kernel/aster-nix/src/syscall/rt_sigreturn.rs b/kernel/aster-nix/src/syscall/rt_sigreturn.rs index bd45365f9..a4233826e 100644 --- a/kernel/aster-nix/src/syscall/rt_sigreturn.rs +++ b/kernel/aster-nix/src/syscall/rt_sigreturn.rs @@ -1,5 +1,7 @@ // SPDX-License-Identifier: MPL-2.0 +use core::sync::atomic::Ordering; + use ostd::{cpu::UserContext, user::UserContextApi}; use super::SyscallReturn; @@ -45,7 +47,10 @@ pub fn sys_rt_sigreturn(context: &mut UserContext) -> Result { .copy_to_raw(context.general_regs_mut()); // unblock sig mask let sig_mask = ucontext.uc_sigmask; - posix_thread.sig_mask().lock().unblock(sig_mask); + let old_mask = posix_thread.sig_mask().load(Ordering::Relaxed); + posix_thread + .sig_mask() + .store(old_mask - sig_mask, Ordering::Relaxed); Ok(SyscallReturn::NoReturn) } diff --git a/kernel/aster-nix/src/syscall/rt_sigsuspend.rs b/kernel/aster-nix/src/syscall/rt_sigsuspend.rs index 13e7da74d..5804d74a4 100644 --- a/kernel/aster-nix/src/syscall/rt_sigsuspend.rs +++ b/kernel/aster-nix/src/syscall/rt_sigsuspend.rs @@ -26,8 +26,8 @@ pub fn sys_rt_sigsuspend(sigmask_addr: Vaddr, sigmask_size: usize) -> Result