Nothing to see here, move along
1use crate::mem::frame::SharedFrame;
2use crate::mem::phys::BitmapFrameAllocator;
3use crate::mem::refcount;
4
5crate::kernel_test!(
6 fn increment_then_get() {
7 let frame = BitmapFrameAllocator.allocate().expect("alloc for refcount");
8 let addr = frame.phys_addr();
9 let _ = refcount::increment(addr);
10 let count = refcount::get(addr);
11 assert_eq!(
12 count, 1,
13 "expected refcount 1 after increment, got {}",
14 count
15 );
16 let remaining = refcount::decrement(addr);
17 assert_eq!(remaining, Ok(0), "expected Ok(0) after decrement");
18 drop(frame);
19 }
20);
21
22crate::kernel_test!(
23 fn increment_n_times() {
24 let frame = BitmapFrameAllocator
25 .allocate()
26 .expect("alloc for refcount N");
27 let addr = frame.phys_addr();
28 let n: u16 = 5;
29 (0..n).for_each(|_| {
30 let _ = refcount::increment(addr);
31 });
32 let count = refcount::get(addr);
33 assert_eq!(count, n, "expected refcount {}, got {}", n, count);
34 (0..n).for_each(|_| {
35 let _ = refcount::decrement(addr);
36 });
37 drop(frame);
38 }
39);
40
41crate::kernel_test!(
42 fn decrement_returns_new_count() {
43 let frame = BitmapFrameAllocator.allocate().expect("alloc for dec test");
44 let addr = frame.phys_addr();
45 let _ = refcount::increment(addr);
46 let _ = refcount::increment(addr);
47 let after_first_dec = refcount::decrement(addr);
48 assert_eq!(after_first_dec, Ok(1), "expected Ok(1) after first dec");
49 let after_second_dec = refcount::decrement(addr);
50 assert_eq!(after_second_dec, Ok(0), "expected Ok(0) after second dec");
51 drop(frame);
52 }
53);
54
55crate::kernel_test!(
56 fn high_refcount_survives() {
57 let frame = BitmapFrameAllocator
58 .allocate()
59 .expect("alloc for high refcount");
60 let addr = frame.phys_addr();
61 let n: u16 = 1000;
62 (0..n).for_each(|_| {
63 refcount::increment(addr).expect("increment should succeed");
64 });
65 let count = refcount::get(addr);
66 assert_eq!(count, n, "expected refcount {}, got {}", n, count);
67 (0..n).for_each(|_| {
68 let _ = refcount::decrement(addr);
69 });
70 assert_eq!(refcount::get(addr), 0, "refcount should be 0 after cleanup");
71 drop(frame);
72 }
73);
74
75crate::kernel_test!(
76 fn underflow_returns_err() {
77 let frame = BitmapFrameAllocator
78 .allocate()
79 .expect("alloc for underflow test");
80 let addr = frame.phys_addr();
81 let result = refcount::decrement(addr);
82 assert!(
83 result.is_err(),
84 "decrement from 0 must return Err to prevent double-free, got {:?}",
85 result
86 );
87 assert_eq!(
88 refcount::get(addr),
89 0,
90 "count must remain 0 after underflow"
91 );
92 drop(frame);
93 }
94);
95
96crate::kernel_test!(
97 fn overflow_returns_error() {
98 let frame = BitmapFrameAllocator
99 .allocate()
100 .expect("alloc for overflow test");
101 let addr = frame.phys_addr();
102 (0..u16::MAX).for_each(|i| {
103 refcount::increment(addr).unwrap_or_else(|_| panic!("increment {} should succeed", i));
104 });
105 assert_eq!(refcount::get(addr), u16::MAX, "should be at u16::MAX");
106 let result = refcount::increment(addr);
107 assert!(
108 result.is_err(),
109 "increment past u16::MAX must return Err, not panic"
110 );
111 (0..u16::MAX).for_each(|_| {
112 let _ = refcount::decrement(addr);
113 });
114 drop(frame);
115 }
116);
117
118crate::kernel_test!(
119 fn into_shared_returns_some_for_valid_frame() {
120 let frame = BitmapFrameAllocator
121 .allocate()
122 .expect("alloc for into_shared test");
123 let addr = frame.phys_addr();
124 let shared: Option<SharedFrame> = frame.into_shared();
125 assert!(
126 shared.is_some(),
127 "into_shared on valid frame must return Some"
128 );
129 assert_eq!(
130 refcount::get(addr),
131 1,
132 "refcount should be 1 after into_shared"
133 );
134 drop(shared);
135 }
136);
137
138crate::kernel_test!(
139 fn duplicate_returns_some_for_valid_frame() {
140 let frame = BitmapFrameAllocator
141 .allocate()
142 .expect("alloc for duplicate test");
143 let addr = frame.phys_addr();
144 let shared = frame.into_shared().expect("into_shared should succeed");
145 let dup: Option<SharedFrame> = shared.duplicate();
146 assert!(
147 dup.is_some(),
148 "duplicate on valid shared frame must return Some"
149 );
150 assert_eq!(
151 refcount::get(addr),
152 2,
153 "refcount should be 2 after duplicate"
154 );
155 drop(dup);
156 assert_eq!(
157 refcount::get(addr),
158 1,
159 "refcount should be 1 after dropping dup"
160 );
161 drop(shared);
162 assert_eq!(
163 refcount::get(addr),
164 0,
165 "refcount should be 0 after dropping original"
166 );
167 }
168);