1 /* 2 * Copyright (c) 2016 Nordic Semiconductor ASA 3 * Copyright (c) 2016 Vinayak Kariappa Chettimada 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 */ 7 8 #ifndef MALIGN 9 /** 10 * @brief Force compiler to place memory at-least on a x-byte boundary 11 * @details Compiler extension. Supported by GCC and Clang 12 */ 13 #define MALIGN(x) __attribute__((aligned(x))) 14 #endif 15 16 #ifndef MROUND 17 /** 18 * @brief Round up to nearest multiple of 4, for unsigned integers 19 * @details 20 * The addition of 3 forces x into the next multiple of 4. This is responsible 21 * for the rounding in the the next step, to be Up. 22 * For ANDing of ~3: We observe y & (~3) == (y>>2)<<2, and we recognize 23 * (y>>2) as a floored division, which is almost undone by the left-shift. The 24 * flooring can't be undone so have achieved a rounding. 25 * 26 * Examples: 27 * MROUND( 0) = 0 28 * MROUND( 1) = 4 29 * MROUND( 2) = 4 30 * MROUND( 3) = 4 31 * MROUND( 4) = 4 32 * MROUND( 5) = 8 33 * MROUND( 8) = 8 34 * MROUND( 9) = 12 35 * MROUND(13) = 16 36 */ 37 #define MROUND(x) (((uint32_t)(x)+3) & (~((uint32_t)3))) 38 #endif 39 40 /* When memory is free in the mem_pool, first few bytes are reserved for 41 * maintaining the next pointer and free count. 42 */ 43 #define MEM_FREE_MEMBER_NEXT_SIZE (sizeof(void *)) 44 #define MEM_FREE_MEMBER_COUNT_SIZE (sizeof(uint16_t)) 45 #define MEM_FREE_RESERVED_SIZE ((MEM_FREE_MEMBER_NEXT_SIZE) + \ 46 (MEM_FREE_MEMBER_COUNT_SIZE)) 47 48 /* Define to check if a structure member is safe to be accessed when the memory 49 * is in the mem_pool free list. I.e. whether a structure member be safely 50 * accessed after the mem being freed. 51 */ 52 #define MEM_FREE_MEMBER_ACCESS_BUILD_ASSERT(type, member) \ 53 BUILD_ASSERT(offsetof(type, member) >= MEM_FREE_RESERVED_SIZE, \ 54 "Possible unsafe member access inside free mem pool") 55 56 void mem_init(void *mem_pool, uint16_t mem_size, uint16_t mem_count, void **mem_head); 57 void *mem_acquire(void **mem_head); 58 void mem_release(void *mem, void **mem_head); 59 60 uint16_t mem_free_count_get(void *mem_head); 61 void *mem_get(const void *mem_pool, uint16_t mem_size, uint16_t index); 62 uint16_t mem_index_get(const void *mem, const void *mem_pool, uint16_t mem_size); 63 64 void mem_rcopy(uint8_t *dst, uint8_t const *src, uint16_t len); 65 uint8_t mem_nz(uint8_t *src, uint16_t len); 66 67 uint32_t mem_ut(void); 68