1use alloc::{sync::Arc, vec::Vec};
6
7use crate::{
8 config::PAGE_SIZE,
9 kernel::current_cpu,
10 mm::{
11 frame_allocator::{FrameTracker, alloc_frames},
12 page_table::{PagingError, UniversalPTEFlag},
13 },
14};
15
16pub struct SharedMemoryTable {
18 memory: Vec<Arc<SharedMemory>>,
19}
20
21impl SharedMemoryTable {
22 pub fn new() -> Self {
24 Self { memory: Vec::new() }
25 }
26
27 pub fn create(&mut self, pages: usize) -> Arc<SharedMemory> {
29 let shm = Arc::new(SharedMemory::new(pages));
30 self.memory.push(shm.clone());
31 shm
32 }
33
34 pub fn remove(&mut self, shm: &Arc<SharedMemory>) -> bool {
36 if let Some(i) = self.memory.iter().position(|x| Arc::ptr_eq(x, shm)) {
37 self.memory.swap_remove(i);
38 true
40 } else {
41 false
42 }
43 }
44
45 pub fn len(&self) -> usize {
47 self.memory.len()
48 }
49
50 pub fn is_empty(&self) -> bool {
51 self.memory.is_empty()
52 }
53}
54
55pub struct SharedMemory {
57 frames: Vec<FrameTracker>,
58 len: usize,
59}
60
61impl SharedMemory {
62 pub fn new(pages: usize) -> Self {
64 let frames = alloc_frames(pages).expect("unable to alloc shared memory");
65 SharedMemory {
66 frames,
67 len: pages * PAGE_SIZE,
68 }
69 }
70
71 pub fn len(&self) -> usize {
73 self.len
74 }
75
76 pub fn is_empty(&self) -> bool {
77 self.len == 0
78 }
79
80 pub fn map_to_user(self) -> Result<usize, PagingError> {
84 let current = {
85 let cpu = current_cpu().lock();
86 cpu.current_task
87 .as_ref()
88 .expect("map_to_user_at: no current task")
89 .clone()
90 };
91 let mut task = current.lock();
92 let space = task
93 .memory_space
94 .as_mut()
95 .expect("map_to_user_at: task has no user memory space");
96
97 let flags = UniversalPTEFlag::READABLE
98 | UniversalPTEFlag::WRITEABLE
99 | UniversalPTEFlag::USER_ACCESSIBLE
100 | UniversalPTEFlag::VALID;
101
102 space.lock().mmap(0, self.len, flags)
103 }
104}