Remove the shim kernel crate

This commit is contained in:
Zhang Junyang
2024-08-19 19:15:22 +08:00
committed by Tate, Hongliang Tian
parent d76c7a5b1e
commit dafd16075f
416 changed files with 231 additions and 273 deletions

View File

@ -0,0 +1,44 @@
// SPDX-License-Identifier: MPL-2.0
/// A trait to represent any events.
///
/// # The unit event
///
/// The unit type `()` can serve as a unit event.
/// It can be used if there is only one kind of event
/// and the event carries no additional information.
pub trait Events: Copy + Clone + Send + Sync + 'static {}
impl Events for () {}
/// A trait to filter events.
///
/// # The no-op event filter
///
/// The unit type `()` can serve as a no-op event filter.
/// It implements `EventsFilter<E>` for any events type `E`,
/// with a `filter` method that always returns `true`.
/// If the `F` type of `Subject<E, F>` is not specified explicitly,
/// then the unit type `()` is chosen as the event filter.
///
/// # Per-object event filter
///
/// Any `Option<F: EventsFilter>` is also an event filter thanks to
/// the blanket implementations the `EventsFilter` trait.
/// By using `Option<F: EventsFilter>`, we can decide, on a per-observer basis,
/// if an observer needs an event filter.
pub trait EventsFilter<E: Events>: Send + Sync + 'static {
fn filter(&self, event: &E) -> bool;
}
impl<E: Events> EventsFilter<E> for () {
fn filter(&self, _events: &E) -> bool {
true
}
}
impl<E: Events, F: EventsFilter<E>> EventsFilter<E> for Option<F> {
fn filter(&self, events: &E) -> bool {
self.as_ref().map_or(true, |f| f.filter(events))
}
}

View File

@ -0,0 +1,25 @@
// SPDX-License-Identifier: MPL-2.0
use super::{Events, EventsFilter};
crate::bitflags! {
pub struct IoEvents: u32 {
const IN = 0x0001;
const PRI = 0x0002;
const OUT = 0x0004;
const ERR = 0x0008;
const HUP = 0x0010;
const NVAL = 0x0020;
const RDHUP = 0x2000;
/// Events that are always polled even without specifying them.
const ALWAYS_POLL = Self::ERR.bits | Self::HUP.bits;
}
}
impl Events for IoEvents {}
impl EventsFilter<IoEvents> for IoEvents {
fn filter(&self, events: &IoEvents) -> bool {
self.intersects(*events)
}
}

15
kernel/src/events/mod.rs Normal file
View File

@ -0,0 +1,15 @@
// SPDX-License-Identifier: MPL-2.0
#[allow(clippy::module_inception)]
mod events;
mod io_events;
mod observer;
mod subject;
pub use io_events::IoEvents;
pub use self::{
events::{Events, EventsFilter},
observer::Observer,
subject::Subject,
};

View File

@ -0,0 +1,39 @@
// SPDX-License-Identifier: MPL-2.0
#![allow(unused_variables)]
use super::Events;
/// An observer for events.
///
/// In a sense, event observers are just a fancy form of callback functions.
/// An observer's `on_events` methods are supposed to be called when
/// some events that are interesting to the observer happen.
///
/// # The no-op observer
///
/// The unit type `()` can serve as a no-op observer.
/// It implements `Observer<E>` for any events type `E`,
/// with an `on_events` method that simply does nothing.
///
/// It can be used to create an empty `Weak`, as shown in the example below.
/// Using the unit type is necessary, as creating an empty `Weak` needs to
/// have a sized type (e.g. the unit type).
///
/// # Examples
///
/// ```
/// use alloc::sync::Weak;
/// use crate::events::Observer;
///
/// let empty: Weak<dyn Observer<()>> = Weak::<()>::new();
/// assert!(empty.upgrade().is_empty());
/// ```
pub trait Observer<E: Events>: Send + Sync {
/// Notify the observer that some interesting events happen.
fn on_events(&self, events: &E);
}
impl<E: Events> Observer<E> for () {
fn on_events(&self, events: &E) {}
}

View File

@ -0,0 +1,93 @@
// SPDX-License-Identifier: MPL-2.0
use core::sync::atomic::{AtomicUsize, Ordering};
use keyable_arc::KeyableWeak;
use super::{Events, EventsFilter, Observer};
use crate::prelude::*;
/// A Subject notifies interesting events to registered observers.
pub struct Subject<E: Events, F: EventsFilter<E> = ()> {
// A table that maintains all interesting observers.
observers: Mutex<BTreeMap<KeyableWeak<dyn Observer<E>>, F>>,
// To reduce lock contentions, we maintain a counter for the size of the table
num_observers: AtomicUsize,
}
impl<E: Events, F: EventsFilter<E>> Subject<E, F> {
pub const fn new() -> Self {
Self {
observers: Mutex::new(BTreeMap::new()),
num_observers: AtomicUsize::new(0),
}
}
/// Register an observer.
///
/// A registered observer will get notified through its `on_events` method.
/// If events `filter` is provided, only filtered events will notify the observer.
///
/// If the given observer has already been registered, then its registered events
/// filter will be updated.
pub fn register_observer(&self, observer: Weak<dyn Observer<E>>, filter: F) {
let mut observers = self.observers.lock();
let is_new = {
let observer: KeyableWeak<dyn Observer<E>> = observer.into();
observers.insert(observer, filter).is_none()
};
if is_new {
self.num_observers.fetch_add(1, Ordering::Relaxed);
}
}
/// Unregister an observer.
///
/// If such an observer is found, then the registered observer will be
/// removed from the subject and returned as the return value. Otherwise,
/// a `None` will be returned.
pub fn unregister_observer(
&self,
observer: &Weak<dyn Observer<E>>,
) -> Option<Weak<dyn Observer<E>>> {
let observer: KeyableWeak<dyn Observer<E>> = observer.clone().into();
let mut observers = self.observers.lock();
let observer = observers
.remove_entry(&observer)
.map(|(observer, _)| observer.into());
if observer.is_some() {
self.num_observers.fetch_sub(1, Ordering::Relaxed);
}
observer
}
/// Notify events to all registered observers.
///
/// It will remove the observers which have been freed.
pub fn notify_observers(&self, events: &E) {
// Fast path.
if self.num_observers.load(Ordering::Relaxed) == 0 {
return;
}
// Slow path: broadcast the new events to all observers.
let mut observers = self.observers.lock();
observers.retain(|observer, filter| {
if let Some(observer) = observer.upgrade() {
if !filter.filter(events) {
return true;
}
observer.on_events(events);
true
} else {
self.num_observers.fetch_sub(1, Ordering::Relaxed);
false
}
});
}
}
impl<E: Events> Default for Subject<E> {
fn default() -> Self {
Self::new()
}
}