support c11mutex test now

This commit is contained in:
PanQL 2020-03-26 14:39:44 +08:00
parent 3585f59ba4
commit dd3da76fac
6 changed files with 61 additions and 10 deletions

View File

@ -126,6 +126,8 @@ pub trait KernelObject: DowncastSync + Debug {
fn set_name(&self, name: &str);
fn signal(&self) -> 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 get_child(&self, _id: KoID) -> ZxResult<Arc<dyn KernelObject>> {
Err(ZxError::WRONG_TYPE)
@ -148,6 +150,7 @@ impl_downcast!(sync KernelObject);
/// The base struct of a kernel object.
pub struct KObjectBase {
pub id: KoID,
pub allowed_signals: Signal,
inner: Mutex<KObjectBaseInner>,
}
@ -178,6 +181,7 @@ impl Default for KObjectBase {
fn default() -> Self {
KObjectBase {
id: Self::new_koid(),
allowed_signals: Signal::USER_ALL,
inner: Default::default(),
}
}
@ -193,6 +197,7 @@ impl KObjectBase {
pub fn with_signal(signal: Signal) -> Self {
KObjectBase {
id: Self::new_koid(),
allowed_signals: Signal::USER_ALL,
inner: Mutex::new(KObjectBaseInner {
signal,
..Default::default()
@ -204,6 +209,7 @@ impl KObjectBase {
pub fn with_name(name: &str) -> Self {
KObjectBase {
id: Self::new_koid(),
allowed_signals: Signal::USER_ALL,
inner: Mutex::new(KObjectBaseInner {
name: String::from(name),
..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.
fn new_koid() -> KoID {
static KOID: AtomicU64 = AtomicU64::new(1024);
@ -436,6 +447,12 @@ macro_rules! impl_kobject {
fn signal_set(&self, signal: 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) {
self.base.add_signal_callback(callback);
}

View File

@ -48,8 +48,8 @@ bitflags! {
}
impl Signal {
pub fn verify_user_signal(number: u32) -> ZxResult<Signal> {
if (number & !Signal::USER_ALL.bits()) != 0 {
pub fn verify_user_signal(allowed_signals: Signal, number: u32) -> ZxResult<Signal> {
if (number & !allowed_signals.bits()) != 0 {
Err(ZxError::INVALID_ARGS)
} else {
Ok(Signal::from_bits(number).ok_or(ZxError::INVALID_ARGS)?)

View File

@ -9,7 +9,19 @@ use alloc::sync::{Arc, Weak};
/// Events are user-signalable objects. The 8 signal bits reserved for
/// userspace (`ZX_USER_SIGNAL_0` through `ZX_USER_SIGNAL_7`) may be set,
/// 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
///
@ -31,11 +43,11 @@ impl EventPair {
#[allow(unsafe_code)]
pub fn create() -> (Arc<Self>, Arc<Self>) {
let mut event0 = Arc::new(EventPair {
base: KObjectBase::default(),
base: KObjectBase::default().set_allowed_signals(Signal::SIGCHLD),
peer: Weak::default(),
});
let event1 = Arc::new(EventPair {
base: KObjectBase::default(),
base: KObjectBase::default().set_allowed_signals(Signal::SIGCHLD),
peer: Arc::downgrade(&event0),
});
// no other reference of `channel0`

View File

@ -16,11 +16,11 @@ impl Syscall<'_> {
info!("clock.get: id={}", clock_id);
match clock_id {
ZX_CLOCK_MONOTONIC => {
time.write(timer_now().as_secs())?;
time.write(timer_now().as_nanos() as u64)?;
Ok(0)
}
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)
}
ZX_CLOCK_THREAD => unimplemented!(),

View File

@ -168,6 +168,7 @@ impl Syscall<'_> {
a5 as _,
a6.into(),
),
Sys::OBJECT_SIGNAL => self.sys_object_signal(a0 as _, a1 as _, a2 as _),
_ => {
warn!("syscall unimplemented: {:?}", sys_type);
Err(ZxError::NOT_SUPPORTED)

View File

@ -138,7 +138,7 @@ impl Syscall<'_> {
);
let proc = self.thread.proc();
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)
}
@ -191,8 +191,9 @@ impl Syscall<'_> {
);
let proc = self.thread.proc();
let object = proc.get_dyn_object_with_rights(handle_value, Rights::SIGNAL_PEER)?;
let clear_signal = Signal::verify_user_signal(clear_mask)?;
let set_signal = Signal::verify_user_signal(set_mask)?;
let allowed_signals = object.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.user_signal_peer(clear_signal, set_signal)?;
Ok(0)
}
@ -220,6 +221,26 @@ impl Syscall<'_> {
object.send_signal_to_port_async(signals, &port, key);
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)]