Sfoglia il codice sorgente

Replace `intr_wait` with `intr_query`

徐启航 1 anno fa
parent
commit
a931d2694a

+ 7 - 40
h2o/kernel/src/cpu/intr/imp.rs

@@ -7,7 +7,7 @@ use super::arch::MANAGER;
 use crate::{
     cpu::time::Instant,
     dev::Resource,
-    sched::{task::hdl::DefaultFeature, Event, EventData, PREEMPT, SIG_GENERIC},
+    sched::{task::hdl::DefaultFeature, Event, EventData, SIG_GENERIC},
 };
 
 const MAX_TIMES: usize = 100;
@@ -92,7 +92,6 @@ mod syscall {
         cpu::{
             arch::apic::{Polarity, TriggerMode},
             intr::arch::MANAGER,
-            time,
         },
         sched::SCHED,
         syscall::{Out, UserPtr},
@@ -129,48 +128,16 @@ mod syscall {
         SCHED.with_current(|cur| unsafe { cur.space().handles().insert_raw(intr, Some(event)) })
     }
 
-    // fn intr_query(hdl: Handle, last_time: UserPtr<Out, u128>) -> Result {
-    //     hdl.check_null()?;
-    //     last_time.check()?;
-
-    //     SCHED.with_current(|cur| {
-    //         let intr = cur.space().handles().get::<Interrupt>(hdl)?;
-    //         let data = intr.last_time().ok_or(ENOENT)?;
-    //         last_time.write(unsafe { data.raw() })
-    //     })
-    // }
-
     #[syscall]
-    fn intr_wait(hdl: Handle, timeout_us: u64, last_time: UserPtr<Out, u128>) -> Result {
+    fn intr_query(hdl: Handle, last_time: UserPtr<Out, u128>) -> Result {
         hdl.check_null()?;
         last_time.check()?;
 
-        let pree = PREEMPT.lock();
-        let intr_obj = unsafe { (*SCHED.current()).as_ref().ok_or(ESRCH)? }
-            .space()
-            .handles()
-            .get::<Interrupt>(hdl)?;
-        if !intr_obj.features().contains(Feature::WAIT) {
-            return Err(EPERM);
-        }
-        let intr = Arc::clone(&intr_obj);
-        drop(intr_obj);
-
-        if timeout_us > 0 {
-            let blocker = crate::sched::Blocker::new(
-                &(Arc::clone(&intr) as _),
-                intr.level_triggered,
-                false,
-                SIG_GENERIC,
-            );
-            blocker.wait(Some(pree), time::from_us(timeout_us))?;
-            if !blocker.detach().0 {
-                return Err(ETIME);
-            }
-        }
-
-        last_time.write(unsafe { intr.last_time().unwrap().raw() })?;
-        Ok(())
+        SCHED.with_current(|cur| {
+            let intr = cur.space().handles().get::<Interrupt>(hdl)?;
+            let data = intr.last_time().ok_or(ENOENT)?;
+            last_time.write(unsafe { data.raw() })
+        })
     }
 
     #[syscall]

+ 1 - 5
h2o/kernel/syscall/interrupt.json

@@ -22,17 +22,13 @@
             ]
         },
         {
-            "name": "sv_intr_wait",
+            "name": "sv_intr_query",
             "returns": "()",
             "args": [
                 {
                     "name": "hdl",
                     "ty": "Handle"
                 },
-                {
-                    "name": "timeout_us",
-                    "ty": "u64"
-                },
                 {
                     "name": "last_time",
                     "ty": "*mut ()"

+ 24 - 40
src/lib/h2o_async/src/dev.rs

@@ -3,11 +3,10 @@ use core::{
     num::NonZeroUsize,
     pin::Pin,
     task::{Context, Poll},
-    time::Duration,
 };
 
 use solvent::{
-    prelude::{PackIntrWait, Result, SerdeReg, Syscall, EPIPE, SIG_GENERIC},
+    prelude::{PackIntrWait, Result, SerdeReg, Syscall, ENOENT, EPIPE, SIG_GENERIC},
     time::Instant,
 };
 use solvent_core::{sync::channel::oneshot, thread::Backoff};
@@ -48,23 +47,17 @@ impl Interrupt {
 
     #[inline]
     pub fn last_time(&self) -> Result<Instant> {
-        self.inner.wait(Duration::ZERO)
+        self.inner.last_time()
     }
 
     #[inline]
-    pub fn wait_until(&self, deadline: Instant) -> WaitUntil<'_> {
-        WaitUntil {
+    pub fn wait_next(&self) -> WaitNext<'_> {
+        WaitNext {
             intr: self,
-            deadline,
             result: None,
             key: None,
         }
     }
-
-    #[inline]
-    pub async fn wait_next(&self) -> Result<Instant> {
-        self.wait_until(Instant::now()).await
-    }
 }
 
 unsafe impl PackedSyscall for (PackIntrWait, oneshot::Sender<Result<Instant>>) {
@@ -81,14 +74,13 @@ unsafe impl PackedSyscall for (PackIntrWait, oneshot::Sender<Result<Instant>>) {
 }
 
 #[must_use]
-pub struct WaitUntil<'a> {
+pub struct WaitNext<'a> {
     intr: &'a Interrupt,
-    deadline: Instant,
     result: Option<oneshot::Receiver<Result<Instant>>>,
     key: Option<usize>,
 }
 
-impl Future for WaitUntil<'_> {
+impl Future for WaitNext<'_> {
     type Output = Result<Instant>;
 
     fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
@@ -101,38 +93,30 @@ impl Future for WaitUntil<'_> {
             return Poll::Pending;
         }
 
-        let mut last_time = self.intr.last_time()?;
-        if self.deadline <= last_time {
-            return Poll::Ready(Ok(last_time));
-        }
-
         let backoff = Backoff::new();
         let (mut tx, rx) = oneshot();
         self.result = Some(rx);
         loop {
-            let pack = if self.deadline > last_time {
-                let pack = self.intr.inner.pack_wait(self.deadline - last_time)?;
-                let res = self.intr.disp.poll_send(
-                    &self.intr.inner,
-                    true,
-                    SIG_GENERIC,
-                    (pack, tx),
-                    cx.waker(),
-                );
-                match res {
-                    Err((_, pack)) => pack,
-                    Ok(Err(err)) => panic!("poll send: {err:?}"),
-                    Ok(Ok(key)) => {
-                        self.key = Some(key);
-                        break Poll::Pending;
+            match self.intr.inner.last_time() {
+                Err(ENOENT) => {
+                    match self.intr.disp.poll_send(
+                        &self.intr.inner,
+                        true,
+                        SIG_GENERIC,
+                        (self.intr.inner.pack_query()?, tx),
+                        cx.waker(),
+                    ) {
+                        Err(pack) => tx = pack.1,
+                        Ok(Err(err)) => panic!("poll send: {err:?}"),
+                        Ok(Ok(key)) => {
+                            self.key = Some(key);
+                            return Poll::Pending;
+                        }
                     }
                 }
-            } else {
-                break Poll::Ready(Ok(last_time));
-            };
-            tx = pack;
-            backoff.snooze();
-            last_time = self.intr.last_time()?;
+                res => return Poll::Ready(res),
+            }
+            backoff.snooze()
         }
     }
 }

+ 5 - 15
src/lib/h2o_rs/src/dev/intr.rs

@@ -1,5 +1,3 @@
-use core::time::Duration;
-
 pub use sv_call::res::IntrConfig;
 use sv_call::{c_ty::Status, Syscall, ETIME, SV_INTERRUPT};
 
@@ -23,29 +21,21 @@ impl Interrupt {
         }
     }
 
-    pub fn wait(&self, timeout: Duration) -> Result<Instant> {
+    pub fn last_time(&self) -> Result<Instant> {
         let mut ins = 0u128;
         unsafe {
             // SAFETY: We don't move the ownership of the handle.
-            sv_call::sv_intr_wait(
-                unsafe { self.raw() },
-                crate::time::try_into_us(timeout)?,
-                &mut ins as *mut _ as *mut _,
-            )
-            .into_res()?;
+            sv_call::sv_intr_query(unsafe { self.raw() }, &mut ins as *mut _ as *mut _)
+                .into_res()?;
         }
         Ok(unsafe { Instant::from_raw(ins) })
     }
 
-    pub fn pack_wait(&self, timeout: Duration) -> Result<PackIntrWait> {
+    pub fn pack_query(&self) -> Result<PackIntrWait> {
         let mut ins = 0u128;
         let syscall = unsafe {
             // SAFETY: We don't move the ownership of the handle.
-            sv_call::sv_pack_intr_wait(
-                unsafe { self.raw() },
-                crate::time::try_into_us(timeout)?,
-                &mut ins as *mut _ as *mut _,
-            )
+            sv_call::sv_pack_intr_query(unsafe { self.raw() }, &mut ins as *mut _ as *mut _)
         };
         Ok(PackIntrWait { ins, syscall })
     }