Next Generation WASM Microkernel Operating System
1// Copyright 2025 Jonas Kruckenberg
2//
3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// http://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8use crate::sync::wait_cell::WaitCell;
9use crate::time::Ticks;
10use cordyceps::{Linked, list};
11use core::marker::PhantomPinned;
12use core::mem::offset_of;
13use core::ptr::NonNull;
14use core::sync::atomic::{AtomicBool, Ordering};
15use pin_project::pin_project;
16use util::loom_const_fn;
17
18/// An entry in a timing [`Wheel`][crate::time::timer::Wheel].
19#[pin_project]
20#[derive(Debug)]
21pub(in crate::time) struct Entry {
22 pub(in crate::time) deadline: Ticks,
23 pub(in crate::time) is_registered: AtomicBool,
24 /// The currently-registered waker
25 pub(in crate::time) waker: WaitCell,
26 #[pin]
27 links: list::Links<Self>,
28 // This type is !Unpin due to the heuristic from:
29 // <https://github.com/rust-lang/rust/pull/82834>
30 _pin: PhantomPinned,
31}
32
33impl Entry {
34 loom_const_fn! {
35 pub(in crate::time) const fn new(deadline: Ticks) -> Entry {
36 Self {
37 deadline,
38 waker: WaitCell::new(),
39 is_registered: AtomicBool::new(false),
40 links: list::Links::new(),
41 _pin: PhantomPinned,
42 }
43 }
44 }
45
46 pub(in crate::time) fn fire(&self) {
47 let was_registered =
48 self.is_registered
49 .compare_exchange(true, false, Ordering::AcqRel, Ordering::Acquire);
50 tracing::trace!(was_registered = was_registered.is_ok(), "firing sleep!");
51 self.waker.close();
52 }
53}
54
55// Safety: TODO
56unsafe impl Linked<list::Links<Entry>> for Entry {
57 type Handle = NonNull<Self>;
58
59 fn into_ptr(r: Self::Handle) -> NonNull<Self> {
60 r
61 }
62 unsafe fn from_ptr(ptr: NonNull<Self>) -> Self::Handle {
63 ptr
64 }
65 unsafe fn links(ptr: NonNull<Self>) -> NonNull<list::Links<Self>> {
66 ptr.map_addr(|addr| {
67 let offset = offset_of!(Self, links);
68 addr.checked_add(offset).unwrap()
69 })
70 .cast()
71 }
72}