Nothing to see here, move along
at main 168 lines 5.2 kB view raw
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);