ax_runtime/thread/
mm_activation.rs1use alloc::sync::Arc;
4
5use ax_hal::context::InstalledAddressSpace;
6
7use super::TaskError;
8
9#[derive(Debug)]
11pub struct AddressSpaceSwitchProof {
12 cpu: usize,
13}
14
15impl AddressSpaceSwitchProof {
16 #[cfg(feature = "uspace")]
17 pub(super) const fn new(cpu: usize) -> Self {
18 Self { cpu }
19 }
20
21 pub const fn cpu(&self) -> usize {
23 self.cpu
24 }
25}
26
27pub trait SchedulerAddressSpaceOwner: Send + Sync {
32 fn release_after_root_switch(self: Arc<Self>, proof: AddressSpaceSwitchProof);
34 fn cancel_before_install(self: Arc<Self>, cpu: usize);
36 fn abandon(self: Arc<Self>, cpu: usize);
38}
39
40pub unsafe trait UserAddressSpaceOwner: Send + Sync {
48 fn prepare_activation(&self, cpu: usize) -> Result<SchedulerAddressSpaceActivation, TaskError>;
50 fn detach_from_task(&self);
52}
53
54pub struct SchedulerAddressSpaceActivation {
58 installed: InstalledAddressSpace,
59 cpu: usize,
60 owner: Option<Arc<dyn SchedulerAddressSpaceOwner>>,
61 committed: bool,
62}
63
64impl SchedulerAddressSpaceActivation {
65 pub fn new(
67 installed: InstalledAddressSpace,
68 cpu: usize,
69 owner: Arc<dyn SchedulerAddressSpaceOwner>,
70 ) -> Self {
71 Self {
72 installed,
73 cpu,
74 owner: Some(owner),
75 committed: false,
76 }
77 }
78
79 pub const fn installed(&self) -> InstalledAddressSpace {
81 self.installed
82 }
83
84 #[cfg(feature = "uspace")]
85 pub(super) fn commit(&mut self, cpu: usize) {
86 assert_eq!(self.cpu, cpu);
87 assert!(!self.committed);
88 self.committed = true;
89 }
90
91 #[cfg(feature = "uspace")]
92 pub(super) fn release(mut self, proof: AddressSpaceSwitchProof) {
93 assert_eq!(self.cpu, proof.cpu());
94 assert!(self.committed);
95 self.owner
96 .take()
97 .expect("activation is consumed once")
98 .release_after_root_switch(proof);
99 }
100}
101
102impl Drop for SchedulerAddressSpaceActivation {
103 fn drop(&mut self) {
104 if let Some(owner) = self.owner.take() {
105 if self.committed {
106 owner.abandon(self.cpu);
107 } else {
108 owner.cancel_before_install(self.cpu);
109 }
110 }
111 }
112}