| 1 | /* @title: General Purpose Memory Allocator API */ |
| 2 | #pragma once |
| 3 | #include <compiler/core.h> |
| 4 | #include <compiler/wrapper.h> |
| 5 | #include <mem/alloc_param.h> |
| 6 | #include <stddef.h> |
| 7 | #include <stdint.h> |
| 8 | |
| 9 | LOG_SITE_EXTERN(slab); |
| 10 | LOG_HANDLE_EXTERN(slab_flags); |
| 11 | |
| 12 | /* Verify the contract */ |
| 13 | #define ALLOC_PARAMS_CONTRACT(params) \ |
| 14 | ct_precond(ALLOC_FLAGS_VALID((params).flags), \ |
| 15 | "alloc flags set unavailable bits") \ |
| 16 | ct_precond(ALLOC_BEHAVIOR_MAY_FAULT((params).behavior) || \ |
| 17 | !ALLOC_FLAGS_CAN_FAULT((params).flags), \ |
| 18 | "non-faulting alloc behavior cannot request pageable or " \ |
| 19 | "movable memory") \ |
| 20 | ct_precond(!ALLOC_BEHAVIOR_IS_ISR_SAFE((params).behavior) || \ |
| 21 | !((params).flags & ALLOC_FLAG_PAGEABLE), \ |
| 22 | "ISR-safe alloc behavior cannot request pageable " \ |
| 23 | "memory") |
| 24 | |
| 25 | #define ALLOC_SIZE_CONTRACT(size) \ |
| 26 | cc_diagnose_if((size) == 0, "zero-size allocation", "warning") |
| 27 | |
| 28 | #define ALLOC_ALIGN_CONTRACT(align) \ |
| 29 | ct_precond((align) != 0 && ((align) & ((align) - 1)) == 0, \ |
| 30 | "alignment must be a nonzero power of two") |
| 31 | |
| 32 | void *cc_nullable valloc_new(size_t size, struct alloc_params params) |
| 33 | cw_alloc(1) cc_warn_unused_result ALLOC_PARAMS_CONTRACT(params) |
| 34 | ALLOC_SIZE_CONTRACT(size); |
| 35 | void vfree_new(void *ptr, enum alloc_behavior behavior); |
| 36 | |
| 37 | void vfree_full(void *ptr, enum alloc_behavior behavior) |
| 38 | cc_owner_takes(valloc, 1); |
| 39 | void vfree_defer_irq(void *ptr) cc_owner_takes(valloc, 1); |
| 40 | void vfree_aligned_full(void *ptr, enum alloc_behavior behavior) |
| 41 | cc_owner_takes(valloc_aligned, 1); |
| 42 | |
| 43 | void *cc_nullable valloc_from_domain(domain_id_t domain, size_t size) |
| 44 | cw_alloc(2) cc_dealloc(vfree_full, 1) cc_dealloc(vfree_defer_irq, 1) |
| 45 | cc_owner_returns(valloc, 2) cc_warn_unused_result; |
| 46 | |
| 47 | void *cc_nullable valloc_full(size_t size, struct alloc_params params) |
| 48 | cw_alloc(1) cc_dealloc(vfree_full, 1) cc_dealloc(vfree_defer_irq, 1) |
| 49 | cc_owner_returns(valloc, 1) |
| 50 | cc_warn_unused_result ALLOC_PARAMS_CONTRACT(params) |
| 51 | ALLOC_SIZE_CONTRACT(size); |
| 52 | |
| 53 | void *cc_nullable vrealloc_full(void *ptr, size_t size, |
| 54 | struct alloc_params params) cc_alloc_size(2) |
| 55 | cc_warn_unused_result ALLOC_PARAMS_CONTRACT(params); |
| 56 | size_t vsize(void *ptr); |
| 57 | |
| 58 | void *cc_nullable valloc_aligned_full(size_t size, size_t align, |
| 59 | struct alloc_params params) cw_alloc(1, 2) |
| 60 | cc_dealloc(vfree_aligned_full, 1) cc_owner_returns(valloc_aligned, 1) |
| 61 | cc_warn_unused_result ALLOC_PARAMS_CONTRACT(params) |
| 62 | ALLOC_SIZE_CONTRACT(size) ALLOC_ALIGN_CONTRACT(align); |
| 63 | |
| 64 | void *cc_nullable valloc_pages(size_t page_count, enum alloc_flags flags) |
| 65 | cw_alloc() |
| 66 | cc_warn_unused_result ct_precond(ALLOC_FLAGS_VALID(flags), |
| 67 | "alloc flags set unavailable bits" ) |
| 68 | ALLOC_SIZE_CONTRACT(page_count); |
| 69 | bool valloc_ptr_in_slab_validate(void *ptr); |
| 70 | |