forked from rcore-os/zCore
support c11mutex test now
This commit is contained in:
parent
3585f59ba4
commit
dd3da76fac
|
@ -126,6 +126,8 @@ pub trait KernelObject: DowncastSync + Debug {
|
||||||
fn set_name(&self, name: &str);
|
fn set_name(&self, name: &str);
|
||||||
fn signal(&self) -> Signal;
|
fn signal(&self) -> Signal;
|
||||||
fn signal_set(&self, signal: Signal);
|
fn signal_set(&self, signal: Signal);
|
||||||
|
fn signal_change(&self, clear: Signal, set: Signal);
|
||||||
|
fn allowed_signals(&self) -> Signal;
|
||||||
fn add_signal_callback(&self, callback: SignalHandler);
|
fn add_signal_callback(&self, callback: SignalHandler);
|
||||||
fn get_child(&self, _id: KoID) -> ZxResult<Arc<dyn KernelObject>> {
|
fn get_child(&self, _id: KoID) -> ZxResult<Arc<dyn KernelObject>> {
|
||||||
Err(ZxError::WRONG_TYPE)
|
Err(ZxError::WRONG_TYPE)
|
||||||
|
@ -148,6 +150,7 @@ impl_downcast!(sync KernelObject);
|
||||||
/// The base struct of a kernel object.
|
/// The base struct of a kernel object.
|
||||||
pub struct KObjectBase {
|
pub struct KObjectBase {
|
||||||
pub id: KoID,
|
pub id: KoID,
|
||||||
|
pub allowed_signals: Signal,
|
||||||
inner: Mutex<KObjectBaseInner>,
|
inner: Mutex<KObjectBaseInner>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,6 +181,7 @@ impl Default for KObjectBase {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
KObjectBase {
|
KObjectBase {
|
||||||
id: Self::new_koid(),
|
id: Self::new_koid(),
|
||||||
|
allowed_signals: Signal::USER_ALL,
|
||||||
inner: Default::default(),
|
inner: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -193,6 +197,7 @@ impl KObjectBase {
|
||||||
pub fn with_signal(signal: Signal) -> Self {
|
pub fn with_signal(signal: Signal) -> Self {
|
||||||
KObjectBase {
|
KObjectBase {
|
||||||
id: Self::new_koid(),
|
id: Self::new_koid(),
|
||||||
|
allowed_signals: Signal::USER_ALL,
|
||||||
inner: Mutex::new(KObjectBaseInner {
|
inner: Mutex::new(KObjectBaseInner {
|
||||||
signal,
|
signal,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
@ -204,6 +209,7 @@ impl KObjectBase {
|
||||||
pub fn with_name(name: &str) -> Self {
|
pub fn with_name(name: &str) -> Self {
|
||||||
KObjectBase {
|
KObjectBase {
|
||||||
id: Self::new_koid(),
|
id: Self::new_koid(),
|
||||||
|
allowed_signals: Signal::USER_ALL,
|
||||||
inner: Mutex::new(KObjectBaseInner {
|
inner: Mutex::new(KObjectBaseInner {
|
||||||
name: String::from(name),
|
name: String::from(name),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
@ -211,6 +217,11 @@ impl KObjectBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_allowed_signals(mut self, extra_signal: Signal) -> Self {
|
||||||
|
self.allowed_signals = Signal::USER_ALL | extra_signal;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Generate a new KoID.
|
/// Generate a new KoID.
|
||||||
fn new_koid() -> KoID {
|
fn new_koid() -> KoID {
|
||||||
static KOID: AtomicU64 = AtomicU64::new(1024);
|
static KOID: AtomicU64 = AtomicU64::new(1024);
|
||||||
|
@ -436,6 +447,12 @@ macro_rules! impl_kobject {
|
||||||
fn signal_set(&self, signal: Signal) {
|
fn signal_set(&self, signal: Signal) {
|
||||||
self.base.signal_set(signal);
|
self.base.signal_set(signal);
|
||||||
}
|
}
|
||||||
|
fn signal_change(&self, clear: Signal, set: Signal) {
|
||||||
|
self.base.signal_change(clear, set);
|
||||||
|
}
|
||||||
|
fn allowed_signals(&self) -> Signal {
|
||||||
|
self.base.allowed_signals
|
||||||
|
}
|
||||||
fn add_signal_callback(&self, callback: SignalHandler) {
|
fn add_signal_callback(&self, callback: SignalHandler) {
|
||||||
self.base.add_signal_callback(callback);
|
self.base.add_signal_callback(callback);
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,8 +48,8 @@ bitflags! {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Signal {
|
impl Signal {
|
||||||
pub fn verify_user_signal(number: u32) -> ZxResult<Signal> {
|
pub fn verify_user_signal(allowed_signals: Signal, number: u32) -> ZxResult<Signal> {
|
||||||
if (number & !Signal::USER_ALL.bits()) != 0 {
|
if (number & !allowed_signals.bits()) != 0 {
|
||||||
Err(ZxError::INVALID_ARGS)
|
Err(ZxError::INVALID_ARGS)
|
||||||
} else {
|
} else {
|
||||||
Ok(Signal::from_bits(number).ok_or(ZxError::INVALID_ARGS)?)
|
Ok(Signal::from_bits(number).ok_or(ZxError::INVALID_ARGS)?)
|
||||||
|
|
|
@ -9,7 +9,19 @@ use alloc::sync::{Arc, Weak};
|
||||||
/// Events are user-signalable objects. The 8 signal bits reserved for
|
/// Events are user-signalable objects. The 8 signal bits reserved for
|
||||||
/// userspace (`ZX_USER_SIGNAL_0` through `ZX_USER_SIGNAL_7`) may be set,
|
/// userspace (`ZX_USER_SIGNAL_0` through `ZX_USER_SIGNAL_7`) may be set,
|
||||||
/// cleared, and waited upon.
|
/// cleared, and waited upon.
|
||||||
pub type Event = DummyObject;
|
pub struct Event {
|
||||||
|
base: KObjectBase,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_kobject!(Event);
|
||||||
|
|
||||||
|
impl Event {
|
||||||
|
pub fn new() -> Arc<Self> {
|
||||||
|
Arc::new(Event{
|
||||||
|
base: KObjectBase::default().set_allowed_signals(Signal::SIGNALED),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Mutually signalable pair of events for concurrent programming
|
/// Mutually signalable pair of events for concurrent programming
|
||||||
///
|
///
|
||||||
|
@ -31,11 +43,11 @@ impl EventPair {
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
pub fn create() -> (Arc<Self>, Arc<Self>) {
|
pub fn create() -> (Arc<Self>, Arc<Self>) {
|
||||||
let mut event0 = Arc::new(EventPair {
|
let mut event0 = Arc::new(EventPair {
|
||||||
base: KObjectBase::default(),
|
base: KObjectBase::default().set_allowed_signals(Signal::SIGCHLD),
|
||||||
peer: Weak::default(),
|
peer: Weak::default(),
|
||||||
});
|
});
|
||||||
let event1 = Arc::new(EventPair {
|
let event1 = Arc::new(EventPair {
|
||||||
base: KObjectBase::default(),
|
base: KObjectBase::default().set_allowed_signals(Signal::SIGCHLD),
|
||||||
peer: Arc::downgrade(&event0),
|
peer: Arc::downgrade(&event0),
|
||||||
});
|
});
|
||||||
// no other reference of `channel0`
|
// no other reference of `channel0`
|
||||||
|
|
|
@ -16,11 +16,11 @@ impl Syscall<'_> {
|
||||||
info!("clock.get: id={}", clock_id);
|
info!("clock.get: id={}", clock_id);
|
||||||
match clock_id {
|
match clock_id {
|
||||||
ZX_CLOCK_MONOTONIC => {
|
ZX_CLOCK_MONOTONIC => {
|
||||||
time.write(timer_now().as_secs())?;
|
time.write(timer_now().as_nanos() as u64)?;
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
ZX_CLOCK_UTC => {
|
ZX_CLOCK_UTC => {
|
||||||
time.write(timer_now().as_secs() + UTC_OFFSET.load(Ordering::Relaxed))?;
|
time.write(timer_now().as_nanos() as u64 + UTC_OFFSET.load(Ordering::Relaxed))?;
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
ZX_CLOCK_THREAD => unimplemented!(),
|
ZX_CLOCK_THREAD => unimplemented!(),
|
||||||
|
|
|
@ -168,6 +168,7 @@ impl Syscall<'_> {
|
||||||
a5 as _,
|
a5 as _,
|
||||||
a6.into(),
|
a6.into(),
|
||||||
),
|
),
|
||||||
|
Sys::OBJECT_SIGNAL => self.sys_object_signal(a0 as _, a1 as _, a2 as _),
|
||||||
_ => {
|
_ => {
|
||||||
warn!("syscall unimplemented: {:?}", sys_type);
|
warn!("syscall unimplemented: {:?}", sys_type);
|
||||||
Err(ZxError::NOT_SUPPORTED)
|
Err(ZxError::NOT_SUPPORTED)
|
||||||
|
|
|
@ -138,7 +138,7 @@ impl Syscall<'_> {
|
||||||
);
|
);
|
||||||
let proc = self.thread.proc();
|
let proc = self.thread.proc();
|
||||||
let object = proc.get_dyn_object_with_rights(handle, Rights::WAIT)?;
|
let object = proc.get_dyn_object_with_rights(handle, Rights::WAIT)?;
|
||||||
observed.write(object.wait_signal_async(signals).await)?;
|
observed.write_if_not_null(object.wait_signal_async(signals).await)?;
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,8 +191,9 @@ impl Syscall<'_> {
|
||||||
);
|
);
|
||||||
let proc = self.thread.proc();
|
let proc = self.thread.proc();
|
||||||
let object = proc.get_dyn_object_with_rights(handle_value, Rights::SIGNAL_PEER)?;
|
let object = proc.get_dyn_object_with_rights(handle_value, Rights::SIGNAL_PEER)?;
|
||||||
let clear_signal = Signal::verify_user_signal(clear_mask)?;
|
let allowed_signals = object.allowed_signals();
|
||||||
let set_signal = Signal::verify_user_signal(set_mask)?;
|
let clear_signal = Signal::verify_user_signal(allowed_signals, clear_mask)?;
|
||||||
|
let set_signal = Signal::verify_user_signal(allowed_signals, set_mask)?;
|
||||||
object.user_signal_peer(clear_signal, set_signal)?;
|
object.user_signal_peer(clear_signal, set_signal)?;
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
@ -220,6 +221,26 @@ impl Syscall<'_> {
|
||||||
object.send_signal_to_port_async(signals, &port, key);
|
object.send_signal_to_port_async(signals, &port, key);
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn sys_object_signal(
|
||||||
|
&self,
|
||||||
|
handle_value: HandleValue,
|
||||||
|
clear_mask: u32,
|
||||||
|
set_mask: u32,
|
||||||
|
) -> ZxResult<usize> {
|
||||||
|
info!(
|
||||||
|
"object.signal: handle_value={:#x}, clear_mask={:#x}, set_mask={:#x}",
|
||||||
|
handle_value, clear_mask, set_mask
|
||||||
|
);
|
||||||
|
let proc = self.thread.proc();
|
||||||
|
let object = proc.get_dyn_object_with_rights(handle_value, Rights::SIGNAL)?;
|
||||||
|
let allowed_signals = object.allowed_signals();
|
||||||
|
info!("{:?} allowed: {:?}", object.obj_type(), allowed_signals);
|
||||||
|
let clear_signal = Signal::verify_user_signal(allowed_signals, clear_mask)?;
|
||||||
|
let set_signal = Signal::verify_user_signal(allowed_signals, set_mask)?;
|
||||||
|
object.signal_change(clear_signal, set_signal);
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
|
|
Loading…
Reference in New Issue