Nothing to see here, move along
at main 161 lines 5.7 kB view raw
1use crate::cap::pool::POOL; 2use crate::ipc::IpcOutcome; 3use crate::ipc::notification; 4use crate::proc::{PROCESSES, ProcessState}; 5use crate::tests::helpers::alloc_notification_cap; 6use lancer_core::object_layout::NotificationObject; 7 8crate::kernel_test!( 9 fn signal_sets_word_bits() { 10 let (id, generation, cap) = alloc_notification_cap(); 11 let mut ptable = PROCESSES.lock(); 12 notification::do_signal(&cap, 0x0F, &mut ptable).expect("signal"); 13 14 let pool = POOL.lock(); 15 let notif = pool 16 .read_as::<NotificationObject>(id, generation) 17 .expect("read notification"); 18 assert!(notif.word == 0x0F, "word should have bits set"); 19 drop(pool); 20 drop(ptable); 21 let _ = POOL.lock().dec_ref_phys(id, generation); 22 } 23); 24 25crate::kernel_test!( 26 fn signal_accumulates_bits() { 27 let (id, generation, cap) = alloc_notification_cap(); 28 let mut ptable = PROCESSES.lock(); 29 notification::do_signal(&cap, 0x01, &mut ptable).expect("signal 1"); 30 notification::do_signal(&cap, 0x02, &mut ptable).expect("signal 2"); 31 32 let pool = POOL.lock(); 33 let notif = pool 34 .read_as::<NotificationObject>(id, generation) 35 .expect("read notification"); 36 assert!(notif.word == 0x03, "bits should accumulate via OR"); 37 drop(pool); 38 drop(ptable); 39 let _ = POOL.lock().dec_ref_phys(id, generation); 40 } 41); 42 43crate::kernel_test!( 44 fn poll_returns_word_and_clears() { 45 let (id, generation, cap) = alloc_notification_cap(); 46 { 47 let mut pool = POOL.lock(); 48 let notif = pool 49 .write_as::<NotificationObject>(id, generation) 50 .expect("write notification"); 51 notif.word = 0xFF; 52 } 53 let val = notification::do_poll(&cap).expect("poll"); 54 assert!(val == 0xFF, "poll should return accumulated word"); 55 56 let val2 = notification::do_poll(&cap).expect("poll again"); 57 assert!(val2 == 0, "second poll should return 0 after clear"); 58 59 let _ = POOL.lock().dec_ref_phys(id, generation); 60 } 61); 62 63crate::kernel_test!( 64 fn wait_with_pending_returns_immediately() { 65 let (id, generation, cap) = alloc_notification_cap(); 66 let mut allocator = crate::mem::phys::BitmapFrameAllocator; 67 let mut ptable = PROCESSES.lock(); 68 69 let created = ptable.allocate(&mut allocator).expect("alloc"); 70 ptable.start(created).expect("start"); 71 let pid = created.pid(); 72 ptable.simulate_dispatch(pid); 73 74 { 75 let mut pool = POOL.lock(); 76 let notif = pool 77 .write_as::<NotificationObject>(id, generation) 78 .expect("write notification"); 79 notif.word = 0xAB; 80 } 81 82 let result = notification::do_wait(&cap, pid, &mut ptable).expect("wait"); 83 match result { 84 IpcOutcome::Done(bits) => assert!(bits == 0xAB, "should return pending word"), 85 IpcOutcome::Blocked => panic!("should not block when word is pending"), 86 } 87 88 ptable.destroy(pid, &mut allocator); 89 let _ = POOL.lock().dec_ref_phys(id, generation); 90 } 91); 92 93crate::kernel_test!( 94 fn wait_without_pending_blocks() { 95 let (id, generation, cap) = alloc_notification_cap(); 96 let mut allocator = crate::mem::phys::BitmapFrameAllocator; 97 let mut ptable = PROCESSES.lock(); 98 99 let created = ptable.allocate(&mut allocator).expect("alloc"); 100 ptable.start(created).expect("start"); 101 let pid = created.pid(); 102 ptable.simulate_dispatch(pid); 103 104 let result = notification::do_wait(&cap, pid, &mut ptable).expect("wait"); 105 match result { 106 IpcOutcome::Blocked => { 107 assert!( 108 ptable[pid].state() == ProcessState::Blocked, 109 "process should be Blocked" 110 ); 111 } 112 IpcOutcome::Done(_) => panic!("should block when no word pending"), 113 } 114 115 ptable.destroy(pid, &mut allocator); 116 let _ = POOL.lock().dec_ref_phys(id, generation); 117 } 118); 119 120crate::kernel_test!( 121 fn signal_wakes_blocked_waiter() { 122 let (id, generation, cap) = alloc_notification_cap(); 123 let mut allocator = crate::mem::phys::BitmapFrameAllocator; 124 let mut ptable = PROCESSES.lock(); 125 126 let created = ptable.allocate(&mut allocator).expect("alloc"); 127 ptable.start(created).expect("start"); 128 let pid = created.pid(); 129 ptable.simulate_dispatch(pid); 130 131 let result = notification::do_wait(&cap, pid, &mut ptable).expect("wait"); 132 assert!(matches!(result, IpcOutcome::Blocked)); 133 134 notification::do_signal(&cap, 0xDEAD, &mut ptable).expect("signal"); 135 136 assert!( 137 ptable[pid].state() == ProcessState::Ready, 138 "waiter should be unblocked after signal" 139 ); 140 assert!( 141 ptable.exec(pid).unwrap().saved_context.rdx == 0xDEAD, 142 "waiter's rdx should hold the signaled word" 143 ); 144 assert!( 145 ptable.exec(pid).unwrap().saved_context.rax == 0, 146 "waiter's rax should be 0 (success)" 147 ); 148 149 ptable.destroy(pid, &mut allocator); 150 let _ = POOL.lock().dec_ref_phys(id, generation); 151 } 152); 153 154crate::kernel_test!( 155 fn poll_on_empty_returns_zero() { 156 let (id, generation, cap) = alloc_notification_cap(); 157 let val = notification::do_poll(&cap).expect("poll"); 158 assert!(val == 0, "poll on fresh notification should return 0"); 159 let _ = POOL.lock().dec_ref_phys(id, generation); 160 } 161);