Skip to content

Commit

Permalink
refactor: move the definition of signal to axruntime
Browse files Browse the repository at this point in the history
  • Loading branch information
AuYang261 committed Sep 28, 2023
1 parent b41e412 commit 4aa1140
Show file tree
Hide file tree
Showing 11 changed files with 249 additions and 197 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion api/arceos_posix_api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ static_assertions = "1.1.0"
spin = { version = "0.9" }
lazy_static = { version = "1.4", features = ["spin_no_std"] }
flatten_objects = { path = "../../crates/flatten_objects" }
crate_interface = { path = "../../crates/crate_interface" }

[build-dependencies]
bindgen ={ version = "0.66" }
1 change: 0 additions & 1 deletion api/arceos_posix_api/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ typedef struct {{
"rlimit",
"aibuf",
"sysinfo",
"sighandler_t",
"sigaction",
];
let allow_vars = [
Expand Down
1 change: 1 addition & 0 deletions api/arceos_posix_api/src/imp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ mod stdio;

pub mod io;
pub mod resources;
pub mod signal;
pub mod sys;
pub mod task;
pub mod time;
Expand Down
19 changes: 19 additions & 0 deletions api/arceos_posix_api/src/imp/signal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* Copyright (c) [2023] [Syswonder Community]
* [Rukos] is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/

use axruntime::{k_sigaction, Signal};

/// Set signal handler
pub fn sys_sigaction(
signum: u8,
sigaction: Option<*const k_sigaction>,
oldact: Option<*mut k_sigaction>,
) {
Signal::sigaction(signum as u8, sigaction, oldact);
}
31 changes: 26 additions & 5 deletions api/arceos_posix_api/src/imp/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/

use axerrno::LinuxError;
use axruntime::{timer_deadline_wrapper, timer_interval_wrapper};
use axruntime::Signal;
use core::ffi::{c_int, c_long};
use core::time::Duration;

Expand Down Expand Up @@ -102,17 +102,38 @@ pub unsafe fn sys_setitimer(_which: c_int, _new: *const ctypes::itimerval) -> c_
(*_new).it_interval.tv_usec as u32 * 1000,
)
.as_nanos() as u64;
// call_interface!(SignalIf::timer_interval(which, Some(new_interval)));
timer_interval_wrapper(which, Some(new_interval));
Signal::timer_interval(which, Some(new_interval));

let new_ddl = axhal::time::current_time_nanos()
+ Duration::new(
(*_new).it_value.tv_sec as u64,
(*_new).it_value.tv_usec as u32 * 1000,
)
.as_nanos() as u64;
// call_interface!(SignalIf::timer_deadline(which, Some(new_ddl)));
timer_deadline_wrapper(which, Some(new_ddl));
Signal::timer_deadline(which, Some(new_ddl));
Ok(0)
})
}

/// Set timer to send signal after some time
pub unsafe extern "C" fn sys_getitimer(which: c_int, curr_value: *mut ctypes::itimerval) -> c_int {
syscall_body!(sys_getitimer, {
let ddl = Duration::from_nanos(Signal::timer_deadline(which as usize, None).unwrap());
if ddl.as_nanos() == 0 {
return Err(LinuxError::EINVAL);
}
let mut now: ctypes::timespec = Default::default();
unsafe {
sys_clock_gettime(0, &mut now);
}
let now = Duration::from(now);
if ddl > now {
(*curr_value).it_value = ctypes::timeval::from(ddl - now);
} else {
(*curr_value).it_value = ctypes::timeval::from(Duration::new(0, 0));
}
(*curr_value).it_interval =
Duration::from_nanos(Signal::timer_interval(which as usize, None).unwrap()).into();
Ok(0)
})
}
6 changes: 3 additions & 3 deletions api/arceos_posix_api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ extern crate alloc;
#[cfg(feature = "alloc")]
pub use axruntime::{environ, environ_iter, RX_ENVIRON};

pub use axruntime::SignalIf;
pub use crate_interface;
pub use axruntime::k_sigaction;

#[macro_use]
mod utils;
Expand All @@ -50,9 +49,10 @@ pub mod ctypes;

pub use imp::io::{sys_read, sys_write, sys_writev};
pub use imp::resources::{sys_getrlimit, sys_setrlimit};
pub use imp::signal::sys_sigaction;
pub use imp::sys::sys_sysinfo;
pub use imp::task::{sys_exit, sys_getpid, sys_sched_yield};
pub use imp::time::{sys_clock_gettime, sys_nanosleep, sys_setitimer};
pub use imp::time::{sys_clock_gettime, sys_getitimer, sys_nanosleep, sys_setitimer};

#[cfg(feature = "fd")]
pub use imp::fd_ops::{sys_close, sys_dup, sys_dup2, sys_fcntl};
Expand Down
44 changes: 10 additions & 34 deletions modules/axruntime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ extern crate axlog;

#[cfg(all(target_os = "none", not(test)))]
mod lang_items;
mod signal;
mod trap;

#[cfg(feature = "smp")]
Expand All @@ -41,6 +42,8 @@ mod mp;
#[cfg(feature = "smp")]
pub use self::mp::rust_main_secondary;

pub use self::signal::{k_sigaction, Signal};

#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "alloc")]
Expand Down Expand Up @@ -324,30 +327,6 @@ fn remap_kernel_memory() -> Result<(), axhal::paging::PagingError> {
Ok(())
}

/// Signal interface
#[crate_interface::def_interface]
pub trait SignalIf {
/// Set or get signal
fn signal(signum: i8, on: bool) -> Option<u32>;
/// Set signal action
fn sigaction(signum: u8, sigaction: Option<unsafe extern "C" fn(i32)>);
/// Set or get timer deadline
fn timer_deadline(which: usize, new_deadline: Option<u64>) -> Option<u64>;
/// Set or get timer interval
fn timer_interval(which: usize, new_interval: Option<u64>) -> Option<u64>;
}

/// Cannot call it by use `call_interface!` in posix_api layer
/// Signal interface wrapper
pub fn timer_deadline_wrapper(which: usize, new_deadline: Option<u64>) -> Option<u64> {
crate_interface::call_interface!(SignalIf::timer_deadline(which, new_deadline))
}

/// Signal interface wrapper
pub fn timer_interval_wrapper(which: usize, new_interval: Option<u64>) -> Option<u64> {
crate_interface::call_interface!(SignalIf::timer_interval(which, new_interval))
}

#[cfg(feature = "irq")]
fn init_interrupt() {
use axhal::time::TIMER_IRQ_NUM;
Expand Down Expand Up @@ -375,28 +354,25 @@ fn init_interrupt() {
// timer signal num
let timer = [14, 26, 27];
for which in 0..3 {
let mut ddl =
crate_interface::call_interface!(SignalIf::timer_deadline, which, None).unwrap();
let interval =
crate_interface::call_interface!(SignalIf::timer_interval, which, None).unwrap();
let mut ddl = Signal::timer_deadline(which, None).unwrap();
let interval = Signal::timer_interval(which, None).unwrap();
if ddl != 0 && now_ns >= ddl {
crate_interface::call_interface!(SignalIf::signal, timer[which], true);
Signal::signal(timer[which], true);
if interval == 0 {
ddl = 0;
} else {
ddl += interval;
}
crate_interface::call_interface!(SignalIf::timer_deadline, which, Some(ddl));
Signal::timer_deadline(which, Some(ddl));
}
}
let signal = crate_interface::call_interface!(SignalIf::signal, -1, true).unwrap();
let signal = Signal::signal(-1, true).unwrap();
for signum in 0..32 {
if signal & (1 << signum) != 0
/* TODO: && support mask */
{
crate_interface::call_interface!(SignalIf::sigaction, signum, None);
let signumi8 = signum as i8;
crate_interface::call_interface!(SignalIf::signal, signumi8, false);
Signal::sigaction(signum as u8, None, None);
Signal::signal(signum as i8, false);
}
}
}
Expand Down
163 changes: 163 additions & 0 deletions modules/axruntime/src/signal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/* Copyright (c) [2023] [Syswonder Community]
* [Rukos] is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/

#[cfg(feature = "irq")]
use core::sync::atomic::AtomicI64;
use core::{ffi::c_int, time::Duration};

#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug)]
struct itimerval {
it_interval: Duration,
it_value: Duration,
}

/// sigset_t in kernel
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug, Default)]
pub struct sigset_t {
__bits: [u64; 16],
}

/// sigaction in kernel
#[allow(non_camel_case_types)]
#[allow(dead_code)]
#[derive(Copy, Clone, Debug, Default)]
pub struct k_sigaction {
/// signal handler
pub sa_handler: Option<unsafe extern "C" fn(c_int)>,
/// signal mask
pub sa_mask: sigset_t,
/// signal flags
pub sa_flags: i32,
/// signal restorer
pub sa_restorer: Option<unsafe extern "C" fn()>,
}

/// Signal struct
pub struct Signal {
#[cfg(feature = "irq")]
signal: AtomicI64,
sigaction: [k_sigaction; 32],
timer: [itimerval; 3],
}

unsafe extern "C" fn default_handler(signum: c_int) {
panic!("default_handler, signum: {}", signum);
}

static mut SIGNAL_IF: Signal = Signal {
#[cfg(feature = "irq")]
signal: AtomicI64::new(0),
sigaction: [k_sigaction {
sa_handler: Some(default_handler),
sa_mask: sigset_t { __bits: [0; 16] },
sa_flags: 0,
sa_restorer: None,
}; 32],
// Default::default() is not const
timer: [itimerval {
it_interval: Duration::new(0, 0),
it_value: Duration::new(0, 0),
}; 3],
};

impl Signal {
/// Set signal
/// signum: signal number, if signum < 0, just return current signal
/// on: true: enable signal, false: disable signal
#[cfg(feature = "irq")]
pub fn signal(signum: i8, on: bool) -> Option<u32> {
use core::sync::atomic::Ordering;
if signum >= 32 {
return None;
}
let mut old = unsafe { SIGNAL_IF.signal.load(Ordering::Acquire) };
if signum >= 0 {
loop {
let new;
if on {
new = old | (1 << signum);
} else {
new = old & !(1 << signum);
}

match unsafe {
SIGNAL_IF.signal.compare_exchange_weak(
old,
new,
Ordering::AcqRel,
Ordering::Acquire,
)
} {
Ok(_) => break,
Err(x) => old = x,
}
}
}
Some(old.try_into().unwrap())
}
/// Set signal action
/// signum: signal number
/// sigaction: signal action, if sigaction == None, call the handler
pub fn sigaction(
signum: u8,
sigaction: Option<*const k_sigaction>,
oldact: Option<*mut k_sigaction>,
) {
if signum >= unsafe { SIGNAL_IF.sigaction }.len() as u8 {
return;
}
if let Some(oldact) = oldact {
if !oldact.is_null() {
unsafe { *oldact = SIGNAL_IF.sigaction[signum as usize] };
}
}
match sigaction {
Some(s) => unsafe {
SIGNAL_IF.sigaction[signum as usize] = *s;
},
None => unsafe {
SIGNAL_IF.sigaction[signum as usize].sa_handler.unwrap()(signum as c_int)
},
}
}
/// Set timer
/// which: timer type
/// new_value: new timer value
/// old_value: old timer value
pub fn timer_deadline(which: usize, new_deadline: Option<u64>) -> Option<u64> {
if which >= unsafe { SIGNAL_IF.timer }.len() {
return None;
}
let old = unsafe { SIGNAL_IF.timer }[which].it_value;
if let Some(s) = new_deadline {
unsafe {
SIGNAL_IF.timer[which].it_value = Duration::from_nanos(s);
}
}
Some(old.as_nanos() as u64)
}
/// Set timer interval
/// which: timer type
/// new_interval: new timer interval
/// old_interval: old timer interval
pub fn timer_interval(which: usize, new_interval: Option<u64>) -> Option<u64> {
if which >= unsafe { SIGNAL_IF.timer }.len() {
return None;
}
let old = unsafe { SIGNAL_IF.timer }[which].it_interval;
if let Some(s) = new_interval {
unsafe {
SIGNAL_IF.timer[which].it_interval = Duration::from_nanos(s);
}
}
Some(old.as_nanos() as u64)
}
}
Loading

0 comments on commit 4aa1140

Please sign in to comment.