strat9_kernel/memory/
mapping_index.rs1use alloc::collections::BTreeMap;
4
5use smallvec::SmallVec;
6use x86_64::VirtAddr;
7
8use crate::{
9 capability::CapId, memory::address_space::VmaPageSize, process::task::Pid, sync::SpinLock,
10};
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub struct MappingRef {
15 pub pid: Pid,
17 pub vaddr: VirtAddr,
19 pub page_size: VmaPageSize,
21}
22
23pub struct MappingIndex {
33 index: SpinLock<BTreeMap<CapId, SmallVec<[MappingRef; 4]>>>,
34}
35
36impl MappingIndex {
37 pub fn new() -> Self {
39 Self {
40 index: SpinLock::new(BTreeMap::new()),
41 }
42 }
43
44 pub fn register(&self, cap_id: CapId, mapping: MappingRef) {
46 let mut index = self.index.lock();
47 let mappings = index.entry(cap_id).or_default();
48 if !mappings.iter().any(|existing| *existing == mapping) {
49 mappings.push(mapping);
50 }
51 }
52
53 pub fn unregister(&self, cap_id: CapId, pid: Pid, vaddr: VirtAddr) {
55 let mut index = self.index.lock();
56 let should_remove = if let Some(mappings) = index.get_mut(&cap_id) {
57 mappings.retain(|mapping| !(mapping.pid == pid && mapping.vaddr == vaddr));
58 mappings.is_empty()
59 } else {
60 false
61 };
62 if should_remove {
63 index.remove(&cap_id);
64 }
65 }
66
67 pub fn lookup(&self, cap_id: CapId) -> SmallVec<[MappingRef; 4]> {
69 self.index.lock().get(&cap_id).cloned().unwrap_or_default()
70 }
71
72 pub fn remove_all(&self, cap_id: CapId) -> SmallVec<[MappingRef; 4]> {
74 self.index.lock().remove(&cap_id).unwrap_or_default()
75 }
76}
77
78impl Default for MappingIndex {
79 fn default() -> Self {
81 Self::new()
82 }
83}