forked from arceos-org/arceos
-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
modify axipi to support more callback functions, add "ipi" features t…
…o necessary crates
- Loading branch information
Showing
10 changed files
with
95 additions
and
65 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
use alloc::{boxed::Box, sync::Arc}; | ||
|
||
/// A callback function that will be called when an [`IPIEvent`] is received and handled. | ||
pub struct Callback(Box<dyn FnOnce()>); | ||
|
||
impl Callback { | ||
/// Create a new [`Callback`] with the given function. | ||
pub fn new<F: FnOnce() + 'static>(callback: F) -> Self { | ||
Self(Box::new(callback)) | ||
} | ||
|
||
/// Call the callback function. | ||
pub fn call(self) { | ||
(self.0)() | ||
} | ||
} | ||
|
||
impl<T: FnOnce() + 'static> From<T> for Callback { | ||
fn from(callback: T) -> Self { | ||
Self::new(callback) | ||
} | ||
} | ||
|
||
/// A [`Callback`] that can be called multiple times. It's used for multicast IPI events. | ||
#[derive(Clone)] | ||
pub struct MulticastCallback(Arc<dyn Fn()>); | ||
|
||
impl MulticastCallback { | ||
/// Create a new [`MulticastCallback`] with the given function. | ||
pub fn new<F: Fn() + 'static>(callback: F) -> Self { | ||
Self(Arc::new(callback)) | ||
} | ||
|
||
/// Convert the [`MulticastCallback`] into a [`Callback`]. | ||
pub fn into_unicast(self) -> Callback { | ||
Callback(Box::new(move || { | ||
(self.0)() | ||
})) | ||
} | ||
} | ||
|
||
impl<T: Fn() + 'static> From<T> for MulticastCallback { | ||
fn from(callback: T) -> Self { | ||
Self::new(callback) | ||
} | ||
} | ||
|
||
/// An IPI event that is sent from a source CPU to the target CPU. | ||
pub struct IPIEvent { | ||
pub src_cpu_id: usize, | ||
pub callback: Callback, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,79 +1,50 @@ | ||
use alloc::boxed::Box; | ||
use alloc::collections::VecDeque; | ||
|
||
use crate::{Callback, IPIEvent}; | ||
|
||
/// A queue of IPI events. | ||
/// | ||
/// It internally uses a `VecDeque` to store the events, make it | ||
/// possible to pop these events using FIFO order. | ||
pub struct IPIEventQueue<E: IPIEvent> { | ||
events: VecDeque<IPIEventWrapper<E>>, | ||
} | ||
|
||
/// A trait that all events must implement. | ||
pub trait IPIEvent: 'static { | ||
/// Callback function that will be called when the event is triggered. | ||
fn callback(self); | ||
pub struct IPIEventQueue { | ||
events: VecDeque<IPIEvent>, | ||
} | ||
|
||
struct IPIEventWrapper<E> { | ||
src_cpu_id: usize, | ||
event: E, | ||
} | ||
|
||
impl<E: IPIEvent> IPIEventQueue<E> { | ||
/// Creates a new empty timer list. | ||
impl IPIEventQueue { | ||
/// Create a new empty timer list. | ||
pub fn new() -> Self { | ||
Self { | ||
events: VecDeque::new(), | ||
} | ||
} | ||
|
||
/// Whether there is no event. | ||
#[allow(dead_code)] | ||
#[inline] | ||
pub fn is_empty(&self) -> bool { | ||
self.events.is_empty() | ||
} | ||
|
||
pub fn push(&mut self, src_cpu_id: usize, event: E) { | ||
self.events.push_back(IPIEventWrapper { src_cpu_id, event }); | ||
/// Push a new event into the queue. | ||
pub fn push(&mut self, src_cpu_id: usize, callback: Callback) { | ||
self.events.push_back(IPIEvent { src_cpu_id, callback }); | ||
} | ||
|
||
/// Try to pop the latest event that exists in the queue. | ||
/// | ||
/// Returns `None` if no event is available. | ||
pub fn pop_one(&mut self) -> Option<(usize, E)> { | ||
/// Return `None` if no event is available. | ||
#[must_use] | ||
pub fn pop_one(&mut self) -> Option<(usize, Callback)> { | ||
if let Some(e) = self.events.pop_front() { | ||
Some((e.src_cpu_id, e.event)) | ||
Some((e.src_cpu_id, e.callback)) | ||
} else { | ||
None | ||
} | ||
} | ||
} | ||
|
||
impl<E: IPIEvent> Default for IPIEventQueue<E> { | ||
impl Default for IPIEventQueue { | ||
fn default() -> Self { | ||
Self::new() | ||
} | ||
} | ||
|
||
/// A simple wrapper of a closure that implements the [`IPIEvent`] trait. | ||
/// | ||
/// So that it can be used as in the [`IPIEventQueue`]. | ||
#[derive(Clone)] | ||
pub struct IPIEventFn(Box<&'static dyn Fn()>); | ||
|
||
impl IPIEventFn { | ||
/// Constructs a new [`IPIEventFn`] from a closure. | ||
pub fn new<F>(f: &'static F) -> Self | ||
where | ||
F: Fn(), | ||
{ | ||
Self(Box::new(f)) | ||
} | ||
} | ||
|
||
impl IPIEvent for IPIEventFn { | ||
fn callback(self) { | ||
(self.0)() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters