code wiki / (root) / nx_interrupt_broker_test.nx

nx_interrupt_broker_test.nx source

↩ module page · 115 lines · 5750 B

1// nx_interrupt_broker_test.nx -- smoke for nx_interrupt_broker. 2 3import "nx_syscalls.nx" 4import "nx_interrupt_broker.nx" 5 6func main() -> i64 { 7 let now: nx_size = 1000000 8 9 // 1: enum validity 10 if nx_ib_kind_is_valid(NX_IB_KIND_OPERATOR_INPUT) != 1 { return 1 } 11 if nx_ib_kind_is_valid(NX_IB_KIND_SCHEDULED_TICK) != 1 { return 2 } 12 if nx_ib_kind_is_valid(-1) != 0 { return 3 } 13 if nx_ib_kind_is_valid(7) != 0 { return 4 } 14 if NX_IB_KIND_N != 7 { return 5 } 15 16 if nx_ib_dl_is_valid(NX_IB_DL_INSTANT) != 1 { return 6 } 17 if nx_ib_dl_is_valid(NX_IB_DL_BACKGROUND) != 1 { return 7 } 18 if nx_ib_dl_is_valid(-1) != 0 { return 8 } 19 if nx_ib_dl_is_valid(5) != 0 { return 9 } 20 21 if nx_ib_v_is_valid(NX_IB_V_YIELD) != 1 { return 10 } 22 if nx_ib_v_is_valid(NX_IB_V_DEADLINE_MISSED) != 1 { return 11 } 23 24 // 2: deadline windows (microseconds) 25 if nx_ib_dl_window_us(NX_IB_DL_INSTANT) != 10000 { return 12 } 26 if nx_ib_dl_window_us(NX_IB_DL_REALTIME) != 50000 { return 13 } 27 if nx_ib_dl_window_us(NX_IB_DL_INTERACTIVE) != 200000 { return 14 } 28 if nx_ib_dl_window_us(NX_IB_DL_RESPONSIVE) != 1000000 { return 15 } 29 if nx_ib_dl_window_us(NX_IB_DL_BACKGROUND) != 60000000 { return 16 } 30 31 // 3: critical kinds 32 if nx_ib_kind_is_critical(NX_IB_KIND_OPERATOR_INPUT) != 1 { return 17 } 33 if nx_ib_kind_is_critical(NX_IB_KIND_HEALTH_SIGNAL) != 1 { return 18 } 34 if nx_ib_kind_is_critical(NX_IB_KIND_REALTIME_DEADLINE) != 1 { return 19 } 35 if nx_ib_kind_is_critical(NX_IB_KIND_SCHEDULED_TICK) != 0 { return 20 } 36 if nx_ib_kind_is_critical(NX_IB_KIND_PEER_REQUEST) != 0 { return 21 } 37 38 // 4: construction 39 let b: *NxInterruptBroker = nx_ib_new(16) 40 if b.capacity != 16 { return 22 } 41 if b.n_requests != 0 { return 23 } 42 if nx_ib_pending_count(b) != 0 { return 24 } 43 44 if nx_ib_new(0) != (0 as *NxInterruptBroker) { return 25 } 45 46 // 5: file critical interrupt 47 if nx_ib_file(b, 1001, NX_IB_KIND_OPERATOR_INPUT, NX_IB_DL_REALTIME, 90, 0xCAFE, now) != NX_IB_V_YIELD { return 26 } 48 if b.n_requests != 1 { return 27 } 49 50 // 6: invalid kind/deadline refused 51 if nx_ib_file(b, 1002, 99, NX_IB_DL_REALTIME, 50, 0, now) != NX_IB_V_INVALID { return 28 } 52 if nx_ib_file(b, 1002, NX_IB_KIND_OPERATOR_INPUT, 99, 50, 0, now) != NX_IB_V_INVALID { return 29 } 53 54 // 7: arbitrate -- yieldable op + critical interrupt -> YIELD 55 let op_yield: *NxRunningOp = nx_ib_op_new(2001, 50, now, 100000, now + 1000, 1) 56 if nx_ib_arbitrate(b, 1001, op_yield, now + 5000) != NX_IB_V_YIELD { return 30 } 57 if nx_ib_grants(b) != 1 { return 31 } 58 59 // 8: non-yieldable op + critical interrupt where next checkpoint is BEFORE 60 // deadline (checkpoint at now+1000, deadline at now+50000): YIELD 61 let op_late_yield: *NxRunningOp = nx_ib_op_new(2002, 50, now, 100000, now + 1000, 0) 62 if nx_ib_arbitrate(b, 1001, op_late_yield, now + 5000) != NX_IB_V_YIELD { return 32 } 63 64 // 9: non-yieldable op where checkpoint is PAST deadline -> REFUSED_CRITICAL 65 let op_too_late: *NxRunningOp = nx_ib_op_new(2003, 50, now, 100000, now + 100000, 0) 66 if nx_ib_arbitrate(b, 1001, op_too_late, now + 5000) != NX_IB_V_REFUSED_CRITICAL { return 33 } 67 if nx_ib_refusals(b) != 1 { return 34 } 68 69 // 10: past deadline -> DEADLINE_MISSED 70 let op_any: *NxRunningOp = nx_ib_op_new(2004, 50, now, 100000, now + 1000, 1) 71 if nx_ib_arbitrate(b, 1001, op_any, now + 1000000) != NX_IB_V_DEADLINE_MISSED { return 35 } 72 if nx_ib_deadline_misses(b) != 1 { return 36 } 73 74 // 11: non-critical interrupt + low priority -> CONTINUE 75 nx_ib_file(b, 1101, NX_IB_KIND_PEER_REQUEST, NX_IB_DL_RESPONSIVE, 30, 0, now) 76 let op_hi: *NxRunningOp = nx_ib_op_new(2005, 60, now, 100000, now + 1000, 1) 77 if nx_ib_arbitrate(b, 1101, op_hi, now + 1000) != NX_IB_V_CONTINUE { return 37 } 78 79 // 12: non-critical interrupt with clear priority margin -> YIELD 80 nx_ib_file(b, 1102, NX_IB_KIND_PEER_REQUEST, NX_IB_DL_RESPONSIVE, 80, 0, now) 81 let op_lo: *NxRunningOp = nx_ib_op_new(2006, 50, now, 100000, now + 1000, 1) 82 if nx_ib_arbitrate(b, 1102, op_lo, now + 1000) != NX_IB_V_YIELD { return 38 } 83 84 // 13: unknown request id refused 85 if nx_ib_arbitrate(b, 9999, op_lo, now) != NX_IB_V_INVALID { return 39 } 86 87 // 14: resolve removes from pending 88 let count_before: nx_int = nx_ib_pending_count(b) 89 if nx_ib_resolve(b, 1001) != NX_IB_V_YIELD { return 40 } 90 if nx_ib_pending_count(b) != (count_before - 1) { return 41 } 91 if nx_ib_resolve(b, 9999) != NX_IB_V_INVALID { return 42 } 92 93 // 15: resolve preserves the other requests 94 if nx_ib_arbitrate(b, 1101, op_hi, now + 1000) != NX_IB_V_CONTINUE { return 43 } 95 96 // 16: capacity exceeded 97 let b_full: *NxInterruptBroker = nx_ib_new(2) 98 nx_ib_file(b_full, 1, NX_IB_KIND_OPERATOR_INPUT, NX_IB_DL_INSTANT, 90, 0, now) 99 nx_ib_file(b_full, 2, NX_IB_KIND_OPERATOR_INPUT, NX_IB_DL_INSTANT, 90, 0, now) 100 if nx_ib_file(b_full, 3, NX_IB_KIND_OPERATOR_INPUT, NX_IB_DL_INSTANT, 90, 0, now) != NX_IB_V_INVALID { return 44 } 101 102 // 17: null handling 103 let null_b: *NxInterruptBroker = (0 as i64) as *NxInterruptBroker 104 let null_op: *NxRunningOp = (0 as i64) as *NxRunningOp 105 if nx_ib_file(null_b, 1, NX_IB_KIND_OPERATOR_INPUT, NX_IB_DL_INSTANT, 90, 0, now) != NX_IB_V_NULL { return 45 } 106 if nx_ib_arbitrate(null_b, 1, op_lo, now) != NX_IB_V_NULL { return 46 } 107 if nx_ib_arbitrate(b, 1, null_op, now) != NX_IB_V_NULL { return 47 } 108 if nx_ib_resolve(null_b, 1) != NX_IB_V_NULL { return 48 } 109 if nx_ib_pending_count(null_b) != 0 { return 49 } 110 if nx_ib_deadline_misses(null_b) != 0 { return 50 } 111 if nx_ib_grants(null_b) != 0 { return 51 } 112 if nx_ib_refusals(null_b) != 0 { return 52 } 113 114 return 0 115}