Nothing to see here, move along
at main 234 lines 7.1 kB view raw
1use crate::mem::phys::BitmapFrameAllocator; 2use crate::proc::address_space; 3use crate::proc::{ProcessState, PROCESSES}; 4 5crate::kernel_test!( 6 fn thread_create_shares_pml4() { 7 let mut allocator = BitmapFrameAllocator; 8 let mut ptable = PROCESSES.lock(); 9 10 let parent = ptable.allocate(&mut allocator).expect("alloc parent"); 11 let parent_pid = parent.pid(); 12 let parent_pml4 = ptable[parent_pid].pml4_phys; 13 14 let child = ptable 15 .allocate_thread(parent_pid, &mut allocator) 16 .expect("alloc thread"); 17 let child_pid = child.pid(); 18 19 assert!( 20 ptable[child_pid].pml4_phys == parent_pml4, 21 "thread must share parent PML4" 22 ); 23 24 let refcount = address_space::pml4_ref_get(parent_pml4.raw()); 25 assert!(refcount == 2, "PML4 refcount must be 2, got {}", refcount); 26 27 ptable.destroy(child_pid, &mut allocator); 28 ptable.destroy(parent_pid, &mut allocator); 29 } 30); 31 32crate::kernel_test!( 33 fn thread_create_independent_context() { 34 let mut allocator = BitmapFrameAllocator; 35 let mut ptable = PROCESSES.lock(); 36 37 let parent = ptable.allocate(&mut allocator).expect("alloc parent"); 38 let parent_pid = parent.pid(); 39 40 let child = ptable 41 .allocate_thread(parent_pid, &mut allocator) 42 .expect("alloc thread"); 43 let child_pid = child.pid(); 44 45 assert!( 46 ptable[child_pid].kernel_stack_top != ptable[parent_pid].kernel_stack_top, 47 "thread must have its own kernel stack" 48 ); 49 50 assert!( 51 ptable[child_pid].state() == ProcessState::Created, 52 "thread initial state must be Created" 53 ); 54 55 assert!( 56 child_pid != parent_pid, 57 "thread must have a different PID" 58 ); 59 60 ptable.destroy(child_pid, &mut allocator); 61 ptable.destroy(parent_pid, &mut allocator); 62 } 63); 64 65crate::kernel_test!( 66 fn thread_teardown_preserves_address_space() { 67 let mut allocator = BitmapFrameAllocator; 68 let mut ptable = PROCESSES.lock(); 69 70 let parent = ptable.allocate(&mut allocator).expect("alloc parent"); 71 let parent_pid = parent.pid(); 72 let pml4 = ptable[parent_pid].pml4_phys; 73 74 let child = ptable 75 .allocate_thread(parent_pid, &mut allocator) 76 .expect("alloc thread"); 77 let child_pid = child.pid(); 78 79 assert!(address_space::pml4_ref_get(pml4.raw()) == 2, "refcount should be 2"); 80 81 ptable.destroy(child_pid, &mut allocator); 82 83 assert!( 84 address_space::pml4_ref_get(pml4.raw()) == 1, 85 "refcount should drop to 1 after thread destroy" 86 ); 87 88 assert!( 89 ptable.get(parent_pid).is_some(), 90 "parent must still exist" 91 ); 92 assert!( 93 ptable[parent_pid].pml4_phys == pml4, 94 "parent PML4 must be unchanged" 95 ); 96 97 ptable.destroy(parent_pid, &mut allocator); 98 } 99); 100 101crate::kernel_test!( 102 fn last_thread_teardown_frees_pml4() { 103 let mut allocator = BitmapFrameAllocator; 104 let mut ptable = PROCESSES.lock(); 105 106 let parent = ptable.allocate(&mut allocator).expect("alloc parent"); 107 let parent_pid = parent.pid(); 108 let pml4 = ptable[parent_pid].pml4_phys; 109 110 let child = ptable 111 .allocate_thread(parent_pid, &mut allocator) 112 .expect("alloc thread"); 113 let child_pid = child.pid(); 114 115 ptable.destroy(parent_pid, &mut allocator); 116 117 assert!( 118 address_space::pml4_ref_get(pml4.raw()) == 1, 119 "refcount should be 1 after parent destroy" 120 ); 121 122 ptable.destroy(child_pid, &mut allocator); 123 124 assert!( 125 address_space::pml4_ref_get(pml4.raw()) == 0, 126 "refcount should be 0 after last thread destroy" 127 ); 128 } 129); 130 131crate::kernel_test!( 132 fn fs_base_default_zero() { 133 let mut allocator = BitmapFrameAllocator; 134 let mut ptable = PROCESSES.lock(); 135 136 let parent = ptable.allocate(&mut allocator).expect("alloc parent"); 137 let parent_pid = parent.pid(); 138 139 let child = ptable 140 .allocate_thread(parent_pid, &mut allocator) 141 .expect("alloc thread"); 142 let child_pid = child.pid(); 143 144 assert!( 145 ptable[child_pid].fs_base == 0, 146 "thread fs_base must default to 0" 147 ); 148 assert!( 149 ptable[parent_pid].fs_base == 0, 150 "parent fs_base must default to 0" 151 ); 152 153 ptable.destroy(child_pid, &mut allocator); 154 ptable.destroy(parent_pid, &mut allocator); 155 } 156); 157 158crate::kernel_test!( 159 fn fs_base_stored_per_process() { 160 let mut allocator = BitmapFrameAllocator; 161 let mut ptable = PROCESSES.lock(); 162 163 let parent = ptable.allocate(&mut allocator).expect("alloc parent"); 164 let parent_pid = parent.pid(); 165 166 let child = ptable 167 .allocate_thread(parent_pid, &mut allocator) 168 .expect("alloc thread"); 169 let child_pid = child.pid(); 170 171 ptable[parent_pid].fs_base = 0x7FFF_0000_1000; 172 ptable[child_pid].fs_base = 0x7FFF_0000_2000; 173 174 assert!( 175 ptable[parent_pid].fs_base == 0x7FFF_0000_1000, 176 "parent fs_base mismatch" 177 ); 178 assert!( 179 ptable[child_pid].fs_base == 0x7FFF_0000_2000, 180 "child fs_base mismatch" 181 ); 182 183 ptable.destroy(child_pid, &mut allocator); 184 ptable.destroy(parent_pid, &mut allocator); 185 } 186); 187 188crate::kernel_test!( 189 fn thread_inherits_parent_cnode() { 190 let mut allocator = BitmapFrameAllocator; 191 let mut ptable = PROCESSES.lock(); 192 193 let parent = ptable.allocate(&mut allocator).expect("alloc parent"); 194 let parent_pid = parent.pid(); 195 196 let child = ptable 197 .allocate_thread(parent_pid, &mut allocator) 198 .expect("alloc thread"); 199 let child_pid = child.pid(); 200 201 assert!( 202 ptable[child_pid].root_cnode() == ptable[parent_pid].root_cnode(), 203 "thread must inherit parent's root cnode" 204 ); 205 206 ptable.destroy(child_pid, &mut allocator); 207 ptable.destroy(parent_pid, &mut allocator); 208 } 209); 210 211crate::kernel_test!( 212 fn thread_stack_canary_valid() { 213 let mut allocator = BitmapFrameAllocator; 214 let mut ptable = PROCESSES.lock(); 215 216 let parent = ptable.allocate(&mut allocator).expect("alloc parent"); 217 let parent_pid = parent.pid(); 218 219 let child = ptable 220 .allocate_thread(parent_pid, &mut allocator) 221 .expect("alloc thread"); 222 let child_pid = child.pid(); 223 224 ptable.verify_stack_canary(child_pid); 225 226 assert!( 227 ptable.stack_high_water_mark(child_pid) == 0, 228 "fresh thread stack should have zero high water mark" 229 ); 230 231 ptable.destroy(child_pid, &mut allocator); 232 ptable.destroy(parent_pid, &mut allocator); 233 } 234);