Implement sigsuspend.

This commit is contained in:
4lDO2
2024-08-04 18:31:24 +02:00
parent 33f0df3b27
commit 8e5ddbd654
5 changed files with 34 additions and 22 deletions
+23 -4
View File
@@ -657,11 +657,30 @@ pub unsafe fn sigaltstack(
pub const MIN_SIGALTSTACK_SIZE: usize = 8192;
pub fn currently_pending() -> u64 {
pub fn currently_pending_blocked() -> u64 {
let control = &unsafe { Tcb::current().unwrap() }.os_specific.control;
let w0 = control.word[0].load(Ordering::Relaxed);
let w1 = control.word[1].load(Ordering::Relaxed);
let pending_blocked_lo = w0 & !(w0 >> 32);
let pending_unblocked_hi = w1 & !(w0 >> 32);
pending_blocked_lo | (pending_unblocked_hi << 32)
let allow = (w0 >> 32) | ((w1 >> 32) << 32);
let thread_pending = (w0 & 0xffff_ffff) | ((w1 >> 32) & 0xffff_ffff);
let proc_pending = PROC_CONTROL_STRUCT.pending.load(Ordering::Relaxed);
core::sync::atomic::fence(Ordering::Acquire); // TODO: Correct ordering?
(thread_pending | proc_pending) & !allow
}
pub enum Unreachable {}
pub fn wait_with_mask(mask: u64) -> Result<Unreachable, Error> {
let mut old = 0;
set_sigmask(Some(mask), Some(&mut old))?;
let res = syscall::nanosleep(
&syscall::TimeSpec {
tv_sec: i64::MAX,
tv_nsec: 0,
},
&mut syscall::TimeSpec::default(),
);
set_sigmask(Some(old), None)?;
res?;
unreachable!()
}
+1 -1
View File
@@ -359,7 +359,7 @@ pub unsafe extern "C" fn sigset(
#[no_mangle]
pub unsafe extern "C" fn sigsuspend(sigmask: *const sigset_t) -> c_int {
Sys::sigsuspend(&*sigmask)
Err(Sys::sigsuspend(&*sigmask)).or_minus_one_errno()
}
#[no_mangle]
+4 -2
View File
@@ -155,8 +155,10 @@ impl PalSignal for Sys {
.map(|_| ())
}
fn sigsuspend(set: &sigset_t) -> c_int {
unsafe { e(syscall!(RT_SIGSUSPEND, set as *const sigset_t, NSIG / 8)) as c_int }
fn sigsuspend(set: &sigset_t) -> Errno {
unsafe {
e_raw(syscall!(RT_SIGSUSPEND, set as *const sigset_t, NSIG / 8)).expect_err("must fail")
}
}
unsafe fn sigtimedwait(
+1 -1
View File
@@ -37,7 +37,7 @@ pub trait PalSignal: Pal {
oset: Option<&mut sigset_t>,
) -> Result<(), Errno>;
fn sigsuspend(set: &sigset_t) -> c_int;
fn sigsuspend(set: &sigset_t) -> Errno; // always fails
unsafe fn sigtimedwait(set: *const sigset_t, sig: *mut siginfo_t, tp: *const timespec)
-> c_int;
+5 -14
View File
@@ -246,7 +246,7 @@ impl PalSignal for Sys {
}
fn sigpending(set: &mut sigset_t) -> Result<(), Errno> {
*set = redox_rt::signal::currently_pending();
*set = redox_rt::signal::currently_pending_blocked();
Ok(())
}
@@ -264,20 +264,11 @@ impl PalSignal for Sys {
})
}
fn sigsuspend(set: &sigset_t) -> c_int {
//TODO: correct implementation
let mut oset = sigset_t::default();
if let Err(err) = redox_rt::signal::set_sigmask(Some(*set), Some(&mut oset)) {
Errno::from(err).sync();
return -1;
fn sigsuspend(set: &sigset_t) -> Errno {
match redox_rt::signal::wait_with_mask(*set) {
Ok(_) => unreachable!(),
Err(err) => err.into(),
}
//TODO: wait for signal
Self::sched_yield();
if let Err(err) = redox_rt::signal::set_sigmask(Some(oset), None) {
Errno::from(err).sync();
return -1;
}
0
}
unsafe fn sigtimedwait(