Branch data Line data Source code
1 : : /* 2 : : * Copyright (c) 2018 Intel Corporation 3 : : * 4 : : * SPDX-License-Identifier: Apache-2.0 5 : : */ 6 : : 7 : : #include <stdlib.h> 8 : : #include <zephyr.h> 9 : : #include <init.h> 10 : : #include <errno.h> 11 : : #include <sys/math_extras.h> 12 : : #include <string.h> 13 : : #include <app_memory/app_memdomain.h> 14 : : #include <sys/mutex.h> 15 : : #include <sys/sys_heap.h> 16 : : #include <zephyr/types.h> 17 : : 18 : : #define LOG_LEVEL CONFIG_KERNEL_LOG_LEVEL 19 : : #include <logging/log.h> 20 : : LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); 21 : : 22 : : #ifdef CONFIG_MINIMAL_LIBC_MALLOC 23 : : 24 : : #if (CONFIG_MINIMAL_LIBC_MALLOC_ARENA_SIZE > 0) 25 : : #ifdef CONFIG_USERSPACE 26 : : K_APPMEM_PARTITION_DEFINE(z_malloc_partition); 27 : : #define POOL_SECTION K_APP_DMEM_SECTION(z_malloc_partition) 28 : : #else 29 : : #define POOL_SECTION .bss 30 : : #endif /* CONFIG_USERSPACE */ 31 : : 32 : : #define HEAP_BYTES CONFIG_MINIMAL_LIBC_MALLOC_ARENA_SIZE 33 : : 34 : : Z_GENERIC_SECTION(POOL_SECTION) static struct sys_heap z_malloc_heap; 35 : : Z_GENERIC_SECTION(POOL_SECTION) struct sys_mutex z_malloc_heap_mutex; 36 : : Z_GENERIC_SECTION(POOL_SECTION) static char z_malloc_heap_mem[HEAP_BYTES]; 37 : : 38 : : void *malloc(size_t size) 39 : : { 40 : : int lock_ret; 41 : : 42 : : lock_ret = sys_mutex_lock(&z_malloc_heap_mutex, K_FOREVER); 43 : : __ASSERT_NO_MSG(lock_ret == 0); 44 : : 45 : : void *ret = sys_heap_aligned_alloc(&z_malloc_heap, 46 : : __alignof__(z_max_align_t), 47 : : size); 48 : : if (ret == NULL && size != 0) { 49 : : errno = ENOMEM; 50 : : } 51 : : 52 : : (void) sys_mutex_unlock(&z_malloc_heap_mutex); 53 : : 54 : : return ret; 55 : : } 56 : : 57 : : static int malloc_prepare(const struct device *unused) 58 : : { 59 : : ARG_UNUSED(unused); 60 : : 61 : : sys_heap_init(&z_malloc_heap, z_malloc_heap_mem, HEAP_BYTES); 62 : : sys_mutex_init(&z_malloc_heap_mutex); 63 : : 64 : : return 0; 65 : : } 66 : : 67 : : void *realloc(void *ptr, size_t requested_size) 68 : : { 69 : : int lock_ret; 70 : : 71 : : lock_ret = sys_mutex_lock(&z_malloc_heap_mutex, K_FOREVER); 72 : : __ASSERT_NO_MSG(lock_ret == 0); 73 : : 74 : : void *ret = sys_heap_aligned_realloc(&z_malloc_heap, ptr, 75 : : __alignof__(z_max_align_t), 76 : : requested_size); 77 : : 78 : : if (ret == NULL && requested_size != 0) { 79 : : errno = ENOMEM; 80 : : } 81 : : 82 : : (void) sys_mutex_unlock(&z_malloc_heap_mutex); 83 : : 84 : : return ret; 85 : : } 86 : : 87 : : void free(void *ptr) 88 : : { 89 : : int lock_ret; 90 : : 91 : : lock_ret = sys_mutex_lock(&z_malloc_heap_mutex, K_FOREVER); 92 : : __ASSERT_NO_MSG(lock_ret == 0); 93 : : sys_heap_free(&z_malloc_heap, ptr); 94 : : (void) sys_mutex_unlock(&z_malloc_heap_mutex); 95 : : } 96 : : 97 : : SYS_INIT(malloc_prepare, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); 98 : : #else /* No malloc arena */ 99 : : void *malloc(size_t size) 100 : : { 101 : : ARG_UNUSED(size); 102 : : 103 [ # # ]: 0 : LOG_ERR("CONFIG_MINIMAL_LIBC_MALLOC_ARENA_SIZE is 0"); 104 : 0 : errno = ENOMEM; 105 : : 106 : 0 : return NULL; 107 : : } 108 : : 109 : : void free(void *ptr) 110 : : { 111 : : ARG_UNUSED(ptr); 112 : 0 : } 113 : : 114 : : void *realloc(void *ptr, size_t size) 115 : : { 116 : : ARG_UNUSED(ptr); 117 : 0 : return malloc(size); 118 : : } 119 : : #endif 120 : : 121 : : #endif /* CONFIG_MINIMAL_LIBC_MALLOC */ 122 : : 123 : : #ifdef CONFIG_MINIMAL_LIBC_CALLOC 124 : : void *calloc(size_t nmemb, size_t size) 125 : : { 126 : : void *ret; 127 : : 128 [ # # ]: 0 : if (size_mul_overflow(nmemb, size, &size)) { 129 : 0 : errno = ENOMEM; 130 : 0 : return NULL; 131 : : } 132 : : 133 : 0 : ret = malloc(size); 134 : : 135 [ # # ]: 0 : if (ret != NULL) { 136 : 0 : (void)memset(ret, 0, size); 137 : : } 138 : : 139 : 0 : return ret; 140 : : } 141 : : #endif /* CONFIG_MINIMAL_LIBC_CALLOC */ 142 : : 143 : : #ifdef CONFIG_MINIMAL_LIBC_REALLOCARRAY 144 : : void *reallocarray(void *ptr, size_t nmemb, size_t size) 145 : : { 146 : : #if (CONFIG_MINIMAL_LIBC_MALLOC_ARENA_SIZE > 0) 147 : : if (size_mul_overflow(nmemb, size, &size)) { 148 : : errno = ENOMEM; 149 : : return NULL; 150 : : } 151 : : return realloc(ptr, size); 152 : : #else 153 : 0 : return NULL; 154 : : #endif 155 : : } 156 : : #endif /* CONFIG_MINIMAL_LIBC_REALLOCARRAY */