()
| 763 | } |
| 764 | if a == b { return 3 } |
| 765 | @a = 11 |
| 766 | @b = 22 |
| 767 | if @a != 11 or @b != 22 { return 4 } |
| 768 | |
| 769 | ; Release then reallocate: the freed slot is reused. |
| 770 | if Pool_release<i64>(&p, a) == false { return 5 } |
| 771 | if Pool_release<i64>(&p, a) == true { return 6 } |
| 772 | c: i64* = null |
| 773 | c_result := Pool_alloc<i64>(&p) |
| 774 | match c_result { |
| 775 | Ok(value) -> { c = value } |
| 776 | Err(error) -> { return 7 } |
| 777 | } |
| 778 | if c != a { return 8 } |
| 779 | |
| 780 | ; Interior pointer and foreign pointer are rejected. |
| 781 | interior: i64* = ((b as u64) + 4) as i64* |
| 782 | if Pool_release<i64>(&p, interior) == true { return 9 } |
| 783 | stack_value: i64 = 5 |
| 784 | if Pool_release<i64>(&p, &stack_value) == true { return 10 } |
| 785 | |
| 786 | ; Fill past one chunk (64 slots) to force growth. |
| 787 | i: i64 = 0 |
| 788 | while i < 70 { |
| 789 | grown := Pool_alloc<i64>(&p) |
| 790 | match grown { |
| 791 | Ok(value) -> {} |
| 792 | Err(error) -> { return 11 } |
| 793 | } |
| 794 | i += 1 |
| 795 | } |
| 796 | |
| 797 | Pool_deinit<i64>(&p) |
| 798 | if p.chunks != null { return 12 } |
| 799 | return 0 |
| 800 | } |
| 801 | "#, |
| 802 | ); |
| 803 | assert_eq!(exit, Some(0)); |
| 804 | } |
| 805 | |
| 806 | // The fallible allocator ABI must behave identically in kernel mode, where the |
| 807 | // raw source is the bootstrap buffer plus the boot-registered heap region. |
| 808 | #[test] |
| 809 | fn kernel_fallible_allocator_matches_hosted_behavior() { |
| 810 | let (uart, exit) = run_kernel_hll( |
| 811 | r#" |
| 812 | memory_allocator := import("memory_allocator") |
| 813 | external heap_set_region: (start: u64, end: u64) |
| 814 | external kshutdown: (code: i64) |
| 815 | |
| 816 | fail: (code: i64) { |
| 817 | kshutdown(code) |
| 818 | } |
| 819 | |
| 820 | kmain: () { |
nothing calls this directly
no test coverage detected