56 lines
1.8 KiB
Rust
56 lines
1.8 KiB
Rust
use super::*;
|
|
use domain::scheduler::SchedulerDecision;
|
|
use types::id::{CoreId, IrqId, ThreadId};
|
|
use types::time::TimeSlice;
|
|
|
|
#[test]
|
|
fn tick_continues_when_time_remaining() {
|
|
let (mut k, _) = kernel_with_process();
|
|
let decision = k.handle_tick(CoreId::from_raw(0));
|
|
assert!(matches!(decision, SchedulerDecision::Continue));
|
|
}
|
|
|
|
#[test]
|
|
fn tick_preempts_when_time_expired_and_other_thread_ready() {
|
|
let mut k = test_kernel();
|
|
let mock = MockPlatform::new(1);
|
|
let pool = PagePool::new(PhysicalAddress::from_raw(0x8000_0000), 1024);
|
|
let mut k = Kernel::new(mock, pool);
|
|
|
|
// Boot with quantum=2 so it expires after 2 ticks
|
|
let (pid, tid1) = k.boot(Priority::new(16).unwrap(), TimeSlice::new(2)).unwrap();
|
|
|
|
// Spawn a second thread so scheduler has someone to switch to
|
|
let tid2 = k.spawn_thread_for_test(pid, Priority::new(16).unwrap(), TimeSlice::new(100));
|
|
|
|
// First tick: time remaining
|
|
let d1 = k.handle_tick(CoreId::from_raw(0));
|
|
assert!(matches!(d1, SchedulerDecision::Continue));
|
|
|
|
// Second tick: time expired, should preempt
|
|
let d2 = k.handle_tick(CoreId::from_raw(0));
|
|
assert!(matches!(d2, SchedulerDecision::Preempt(_)));
|
|
}
|
|
|
|
#[test]
|
|
fn interrupt_unknown_irq_returns_none() {
|
|
let (mut k, _) = kernel_with_process();
|
|
assert!(k.handle_interrupt(IrqId::from_raw(99)).is_none());
|
|
}
|
|
|
|
#[test]
|
|
fn interrupt_unblocks_registered_thread() {
|
|
let (mut k, _) = kernel_with_process();
|
|
let tid = ThreadId::from_raw(0);
|
|
let irq = IrqId::from_raw(5);
|
|
|
|
// Register and block the thread on this IRQ
|
|
k.register_irq_for_test(irq, tid);
|
|
k.block_thread_for_test(tid, domain::thread::BlockReason::WaitingForInterrupt(
|
|
types::bounded::CapSlot::new(0).unwrap()
|
|
));
|
|
|
|
let result = k.handle_interrupt(irq);
|
|
assert_eq!(result, Some(tid));
|
|
}
|