strat9_kernel/memory/
cow.rs1use crate::{
22 memory::frame::{frame_flags, get_meta, PhysFrame},
23 sync::SpinLock,
24};
25use core::sync::atomic::{fence, Ordering};
26
27static COW_LOCK: SpinLock<()> = SpinLock::new(());
28
29#[inline]
31fn frame_meta(frame: PhysFrame) -> &'static crate::memory::frame::FrameMeta {
32 get_meta(frame.start_address)
33}
34
35pub fn frame_inc_ref(frame: PhysFrame) {
37 frame_meta(frame).inc_ref();
38}
39
40pub fn frame_dec_ref(frame: PhysFrame) {
42 let meta = frame_meta(frame);
43 let old = meta.dec_ref();
44 if old == 1 {
45 fence(Ordering::Acquire);
46 crate::sync::with_irqs_disabled(|token| {
47 crate::memory::free_frame(token, frame);
48 });
49 }
50}
51
52pub fn frame_get_refcount(frame: PhysFrame) -> u32 {
54 frame_meta(frame).get_refcount()
55}
56
57pub fn frame_set_cow(frame: PhysFrame) {
59 let _lock = COW_LOCK.lock();
60 let meta = frame_meta(frame);
61 let flags = meta.get_flags() | frame_flags::COW;
62 meta.set_flags(flags);
63}
64
65pub fn frame_clear_cow(frame: PhysFrame) {
67 let _lock = COW_LOCK.lock();
68 let meta = frame_meta(frame);
69 let flags = meta.get_flags() & !frame_flags::COW;
70 meta.set_flags(flags);
71}
72
73pub fn frame_is_cow(frame: PhysFrame) -> bool {
75 frame_meta(frame).is_cow()
76}
77
78pub fn frame_set_dll(frame: PhysFrame) {
80 let _lock = COW_LOCK.lock();
81 let meta = frame_meta(frame);
82 let flags = meta.get_flags() | frame_flags::DLL;
83 meta.set_flags(flags);
84}
85
86pub fn frame_is_dll(frame: PhysFrame) -> bool {
88 frame_meta(frame).is_dll()
89}