Nothing to see here, move along meow
1use core::mem::ManuallyDrop;
2
3use x86_64::PhysAddr;
4use x86_64::structures::paging::PhysFrame;
5
6#[derive(Debug)]
7pub struct OwnedFrame {
8 frame: PhysFrame,
9}
10
11impl OwnedFrame {
12 pub(super) fn new(frame: PhysFrame) -> Self {
13 Self { frame }
14 }
15
16 pub fn phys_addr(&self) -> PhysAddr {
17 self.frame.start_address()
18 }
19
20 #[allow(dead_code)]
21 pub fn phys_frame(&self) -> PhysFrame {
22 self.frame
23 }
24
25 pub fn inner(self) -> PhysFrame {
26 let this = ManuallyDrop::new(self);
27 this.frame
28 }
29
30 #[allow(dead_code)]
31 pub fn into_shared(self) -> Option<SharedFrame> {
32 let phys = self.phys_addr();
33 match super::refcount::increment(phys) {
34 Ok(()) => {
35 let frame = ManuallyDrop::new(self).frame;
36 Some(SharedFrame { frame })
37 }
38 Err(_) => None,
39 }
40 }
41}
42
43impl Drop for OwnedFrame {
44 fn drop(&mut self) {
45 super::phys::BitmapFrameAllocator::free_frame_by_addr(self.frame.start_address());
46 }
47}
48
49#[allow(dead_code)]
50pub struct SharedFrame {
51 frame: PhysFrame,
52}
53
54impl SharedFrame {
55 #[cfg(not(lancer_test))]
56 #[allow(dead_code)]
57 pub unsafe fn from_phys(phys: PhysAddr) -> Self {
58 Self {
59 frame: PhysFrame::containing_address(phys),
60 }
61 }
62
63 #[allow(dead_code)]
64 pub fn phys_addr(&self) -> PhysAddr {
65 self.frame.start_address()
66 }
67
68 #[allow(dead_code)]
69 pub fn duplicate(&self) -> Option<SharedFrame> {
70 match super::refcount::increment(self.frame.start_address()) {
71 Ok(()) => Some(SharedFrame { frame: self.frame }),
72 Err(_) => None,
73 }
74 }
75}
76
77impl Drop for SharedFrame {
78 fn drop(&mut self) {
79 match super::refcount::decrement(self.frame.start_address()) {
80 Ok(0) => {
81 super::phys::BitmapFrameAllocator::free_frame_by_addr(self.frame.start_address());
82 }
83 Ok(_) => {}
84 Err(e) => {
85 crate::kprintln!(
86 "[refcount] BUG: SharedFrame drop failed for {:#x}: {:?}. leaking frame",
87 self.frame.start_address().as_u64(),
88 e
89 );
90 }
91 }
92 }
93}
94
95impl core::fmt::Debug for SharedFrame {
96 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
97 f.debug_struct("SharedFrame")
98 .field("phys", &self.frame.start_address())
99 .finish()
100 }
101}