Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Committer:
kenjiArai
Date:
Tue Dec 17 23:23:45 2019 +0000
Revision:
0:5b88d5760320
mbed-os5 only for TYBLE16

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 0:5b88d5760320 1 /*
kenjiArai 0:5b88d5760320 2 * Copyright (c) 2014-2019 ARM Limited. All rights reserved.
kenjiArai 0:5b88d5760320 3 * SPDX-License-Identifier: Apache-2.0
kenjiArai 0:5b88d5760320 4 * Licensed under the Apache License, Version 2.0 (the License); you may
kenjiArai 0:5b88d5760320 5 * not use this file except in compliance with the License.
kenjiArai 0:5b88d5760320 6 * You may obtain a copy of the License at
kenjiArai 0:5b88d5760320 7 *
kenjiArai 0:5b88d5760320 8 * http://www.apache.org/licenses/LICENSE-2.0
kenjiArai 0:5b88d5760320 9 *
kenjiArai 0:5b88d5760320 10 * Unless required by applicable law or agreed to in writing, software
kenjiArai 0:5b88d5760320 11 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
kenjiArai 0:5b88d5760320 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kenjiArai 0:5b88d5760320 13 * See the License for the specific language governing permissions and
kenjiArai 0:5b88d5760320 14 * limitations under the License.
kenjiArai 0:5b88d5760320 15 */
kenjiArai 0:5b88d5760320 16 #include <stdint.h>
kenjiArai 0:5b88d5760320 17 #include <string.h>
kenjiArai 0:5b88d5760320 18 #include "nsdynmemLIB.h"
kenjiArai 0:5b88d5760320 19 #include "platform/arm_hal_interrupt.h"
kenjiArai 0:5b88d5760320 20 #include <stdlib.h>
kenjiArai 0:5b88d5760320 21 #include "ns_list.h"
kenjiArai 0:5b88d5760320 22
kenjiArai 0:5b88d5760320 23 #ifndef STANDARD_MALLOC
kenjiArai 0:5b88d5760320 24 typedef enum mem_stat_update_t {
kenjiArai 0:5b88d5760320 25 DEV_HEAP_ALLOC_OK,
kenjiArai 0:5b88d5760320 26 DEV_HEAP_ALLOC_FAIL,
kenjiArai 0:5b88d5760320 27 DEV_HEAP_FREE,
kenjiArai 0:5b88d5760320 28 } mem_stat_update_t;
kenjiArai 0:5b88d5760320 29
kenjiArai 0:5b88d5760320 30 typedef struct {
kenjiArai 0:5b88d5760320 31 ns_list_link_t link;
kenjiArai 0:5b88d5760320 32 } hole_t;
kenjiArai 0:5b88d5760320 33
kenjiArai 0:5b88d5760320 34 typedef int ns_mem_word_size_t; // internal signed heap block size type
kenjiArai 0:5b88d5760320 35
kenjiArai 0:5b88d5760320 36 // Amount of memory regions
kenjiArai 0:5b88d5760320 37 #define REGION_COUNT 3
kenjiArai 0:5b88d5760320 38
kenjiArai 0:5b88d5760320 39 /* struct for book keeping variables */
kenjiArai 0:5b88d5760320 40 struct ns_mem_book {
kenjiArai 0:5b88d5760320 41 ns_mem_word_size_t *heap_main[REGION_COUNT];
kenjiArai 0:5b88d5760320 42 ns_mem_word_size_t *heap_main_end[REGION_COUNT];
kenjiArai 0:5b88d5760320 43 mem_stat_t *mem_stat_info_ptr;
kenjiArai 0:5b88d5760320 44 void (*heap_failure_callback)(heap_fail_t);
kenjiArai 0:5b88d5760320 45 NS_LIST_HEAD(hole_t, link) holes_list;
kenjiArai 0:5b88d5760320 46 ns_mem_heap_size_t heap_size;
kenjiArai 0:5b88d5760320 47 ns_mem_heap_size_t temporary_alloc_heap_limit; /* Amount of reserved heap temporary alloc can't exceed */
kenjiArai 0:5b88d5760320 48 };
kenjiArai 0:5b88d5760320 49
kenjiArai 0:5b88d5760320 50 static ns_mem_book_t *default_book; // heap pointer for original "ns_" API use
kenjiArai 0:5b88d5760320 51
kenjiArai 0:5b88d5760320 52 // size of a hole_t in our word units
kenjiArai 0:5b88d5760320 53 #define HOLE_T_SIZE ((ns_mem_word_size_t) ((sizeof(hole_t) + sizeof(ns_mem_word_size_t) - 1) / sizeof(ns_mem_word_size_t)))
kenjiArai 0:5b88d5760320 54
kenjiArai 0:5b88d5760320 55 #define TEMPORARY_ALLOC_FREE_HEAP_THRESHOLD 5 /* temporary allocations must leave 5% of the heap free */
kenjiArai 0:5b88d5760320 56
kenjiArai 0:5b88d5760320 57 static NS_INLINE hole_t *hole_from_block_start(ns_mem_word_size_t *start)
kenjiArai 0:5b88d5760320 58 {
kenjiArai 0:5b88d5760320 59 return (hole_t *)(start + 1);
kenjiArai 0:5b88d5760320 60 }
kenjiArai 0:5b88d5760320 61
kenjiArai 0:5b88d5760320 62 static NS_INLINE ns_mem_word_size_t *block_start_from_hole(hole_t *start)
kenjiArai 0:5b88d5760320 63 {
kenjiArai 0:5b88d5760320 64 return ((ns_mem_word_size_t *)start) - 1;
kenjiArai 0:5b88d5760320 65 }
kenjiArai 0:5b88d5760320 66
kenjiArai 0:5b88d5760320 67 static void heap_failure(ns_mem_book_t *book, heap_fail_t reason)
kenjiArai 0:5b88d5760320 68 {
kenjiArai 0:5b88d5760320 69 if (book->heap_failure_callback) {
kenjiArai 0:5b88d5760320 70 book->heap_failure_callback(reason);
kenjiArai 0:5b88d5760320 71 }
kenjiArai 0:5b88d5760320 72 }
kenjiArai 0:5b88d5760320 73
kenjiArai 0:5b88d5760320 74 static int ns_dyn_mem_region_find(ns_mem_book_t *book, ns_mem_word_size_t *block_ptr, ns_mem_word_size_t size)
kenjiArai 0:5b88d5760320 75 {
kenjiArai 0:5b88d5760320 76 int index;
kenjiArai 0:5b88d5760320 77 for (index = 0; index < REGION_COUNT; index++) {
kenjiArai 0:5b88d5760320 78 if (book->heap_main[index] != 0) {
kenjiArai 0:5b88d5760320 79 if ((block_ptr >= book->heap_main[index]) &&
kenjiArai 0:5b88d5760320 80 (block_ptr < book->heap_main_end[index]) &&
kenjiArai 0:5b88d5760320 81 ((block_ptr + size) < book->heap_main_end[index])) {
kenjiArai 0:5b88d5760320 82 return index;
kenjiArai 0:5b88d5760320 83 }
kenjiArai 0:5b88d5760320 84 }
kenjiArai 0:5b88d5760320 85 }
kenjiArai 0:5b88d5760320 86
kenjiArai 0:5b88d5760320 87 return -1;
kenjiArai 0:5b88d5760320 88 }
kenjiArai 0:5b88d5760320 89
kenjiArai 0:5b88d5760320 90 static int ns_dyn_mem_region_save(ns_mem_book_t *book, ns_mem_word_size_t *region_start_ptr, ns_mem_word_size_t region_size)
kenjiArai 0:5b88d5760320 91 {
kenjiArai 0:5b88d5760320 92 for (int i = 1; i < REGION_COUNT; i++) {
kenjiArai 0:5b88d5760320 93 if (book->heap_main[i] == 0) {
kenjiArai 0:5b88d5760320 94 book->heap_main[i] = region_start_ptr;
kenjiArai 0:5b88d5760320 95 book->heap_main_end[i] = book->heap_main[i] + region_size;
kenjiArai 0:5b88d5760320 96 return 0;
kenjiArai 0:5b88d5760320 97 }
kenjiArai 0:5b88d5760320 98 }
kenjiArai 0:5b88d5760320 99
kenjiArai 0:5b88d5760320 100 return -1;
kenjiArai 0:5b88d5760320 101 }
kenjiArai 0:5b88d5760320 102
kenjiArai 0:5b88d5760320 103
kenjiArai 0:5b88d5760320 104 #endif //STANDARD_MALLOC
kenjiArai 0:5b88d5760320 105
kenjiArai 0:5b88d5760320 106 void ns_dyn_mem_init(void *heap, ns_mem_heap_size_t h_size,
kenjiArai 0:5b88d5760320 107 void (*passed_fptr)(heap_fail_t), mem_stat_t *info_ptr)
kenjiArai 0:5b88d5760320 108 {
kenjiArai 0:5b88d5760320 109 default_book = ns_mem_init(heap, h_size, passed_fptr, info_ptr);
kenjiArai 0:5b88d5760320 110 }
kenjiArai 0:5b88d5760320 111
kenjiArai 0:5b88d5760320 112 int ns_dyn_mem_region_add(void *region_ptr, ns_mem_heap_size_t region_size)
kenjiArai 0:5b88d5760320 113 {
kenjiArai 0:5b88d5760320 114 return ns_mem_region_add(default_book, region_ptr, region_size);
kenjiArai 0:5b88d5760320 115 }
kenjiArai 0:5b88d5760320 116
kenjiArai 0:5b88d5760320 117 const mem_stat_t *ns_dyn_mem_get_mem_stat(void)
kenjiArai 0:5b88d5760320 118 {
kenjiArai 0:5b88d5760320 119 #ifndef STANDARD_MALLOC
kenjiArai 0:5b88d5760320 120 return ns_mem_get_mem_stat(default_book);
kenjiArai 0:5b88d5760320 121 #else
kenjiArai 0:5b88d5760320 122 return NULL;
kenjiArai 0:5b88d5760320 123 #endif
kenjiArai 0:5b88d5760320 124 }
kenjiArai 0:5b88d5760320 125
kenjiArai 0:5b88d5760320 126 ns_mem_book_t *ns_mem_init(void *heap, ns_mem_heap_size_t h_size,
kenjiArai 0:5b88d5760320 127 void (*passed_fptr)(heap_fail_t),
kenjiArai 0:5b88d5760320 128 mem_stat_t *info_ptr)
kenjiArai 0:5b88d5760320 129 {
kenjiArai 0:5b88d5760320 130 #ifndef STANDARD_MALLOC
kenjiArai 0:5b88d5760320 131 ns_mem_book_t *book;
kenjiArai 0:5b88d5760320 132
kenjiArai 0:5b88d5760320 133 ns_mem_word_size_t *ptr;
kenjiArai 0:5b88d5760320 134 ns_mem_word_size_t temp_int;
kenjiArai 0:5b88d5760320 135 /* Do memory alignment */
kenjiArai 0:5b88d5760320 136 temp_int = ((uintptr_t)heap % sizeof(ns_mem_word_size_t));
kenjiArai 0:5b88d5760320 137 if (temp_int) {
kenjiArai 0:5b88d5760320 138 heap = (uint8_t *) heap + (sizeof(ns_mem_word_size_t) - temp_int);
kenjiArai 0:5b88d5760320 139 h_size -= (sizeof(ns_mem_word_size_t) - temp_int);
kenjiArai 0:5b88d5760320 140 }
kenjiArai 0:5b88d5760320 141
kenjiArai 0:5b88d5760320 142 /* Make correction for total length also */
kenjiArai 0:5b88d5760320 143 temp_int = (h_size % sizeof(ns_mem_word_size_t));
kenjiArai 0:5b88d5760320 144 if (temp_int) {
kenjiArai 0:5b88d5760320 145 h_size -= (sizeof(ns_mem_word_size_t) - temp_int);
kenjiArai 0:5b88d5760320 146 }
kenjiArai 0:5b88d5760320 147
kenjiArai 0:5b88d5760320 148 book = heap;
kenjiArai 0:5b88d5760320 149 memset(book->heap_main, 0, REGION_COUNT * sizeof(ns_mem_word_size_t *));
kenjiArai 0:5b88d5760320 150 memset(book->heap_main_end, 0, REGION_COUNT * sizeof(ns_mem_word_size_t *));
kenjiArai 0:5b88d5760320 151
kenjiArai 0:5b88d5760320 152 book->heap_main[0] = (ns_mem_word_size_t *) & (book[1]); // SET Heap Pointer
kenjiArai 0:5b88d5760320 153 book->heap_size = h_size - sizeof(ns_mem_book_t); //Set Heap Size
kenjiArai 0:5b88d5760320 154 temp_int = (book->heap_size / sizeof(ns_mem_word_size_t));
kenjiArai 0:5b88d5760320 155 temp_int -= 2;
kenjiArai 0:5b88d5760320 156 ptr = book->heap_main[0];
kenjiArai 0:5b88d5760320 157 *ptr = -(temp_int);
kenjiArai 0:5b88d5760320 158 ptr += (temp_int + 1);
kenjiArai 0:5b88d5760320 159 *ptr = -(temp_int);
kenjiArai 0:5b88d5760320 160 book->heap_main_end[0] = ptr;
kenjiArai 0:5b88d5760320 161
kenjiArai 0:5b88d5760320 162 ns_list_init(&book->holes_list);
kenjiArai 0:5b88d5760320 163 ns_list_add_to_start(&book->holes_list, hole_from_block_start(book->heap_main[0]));
kenjiArai 0:5b88d5760320 164
kenjiArai 0:5b88d5760320 165 book->mem_stat_info_ptr = info_ptr;
kenjiArai 0:5b88d5760320 166 //RESET Memory by Hea Len
kenjiArai 0:5b88d5760320 167 if (info_ptr) {
kenjiArai 0:5b88d5760320 168 memset(book->mem_stat_info_ptr, 0, sizeof(mem_stat_t));
kenjiArai 0:5b88d5760320 169 book->mem_stat_info_ptr->heap_sector_size = book->heap_size;
kenjiArai 0:5b88d5760320 170 }
kenjiArai 0:5b88d5760320 171 book->temporary_alloc_heap_limit = book->heap_size / 100 * (100 - TEMPORARY_ALLOC_FREE_HEAP_THRESHOLD);
kenjiArai 0:5b88d5760320 172 #endif
kenjiArai 0:5b88d5760320 173 //There really is no support to standard malloc in this library anymore
kenjiArai 0:5b88d5760320 174 book->heap_failure_callback = passed_fptr;
kenjiArai 0:5b88d5760320 175
kenjiArai 0:5b88d5760320 176 return book;
kenjiArai 0:5b88d5760320 177 }
kenjiArai 0:5b88d5760320 178
kenjiArai 0:5b88d5760320 179 int ns_mem_region_add(ns_mem_book_t *book, void *region_ptr, ns_mem_heap_size_t region_size)
kenjiArai 0:5b88d5760320 180 {
kenjiArai 0:5b88d5760320 181 #ifndef STANDARD_MALLOC
kenjiArai 0:5b88d5760320 182 if (!book || !region_ptr || region_size < 3 * sizeof(ns_mem_word_size_t)) {
kenjiArai 0:5b88d5760320 183 return -1;
kenjiArai 0:5b88d5760320 184 }
kenjiArai 0:5b88d5760320 185
kenjiArai 0:5b88d5760320 186 ns_mem_word_size_t *block_ptr;
kenjiArai 0:5b88d5760320 187 ns_mem_word_size_t temp_int;
kenjiArai 0:5b88d5760320 188
kenjiArai 0:5b88d5760320 189 /* Do memory alignment */
kenjiArai 0:5b88d5760320 190 temp_int = ((uintptr_t)region_ptr % sizeof(ns_mem_word_size_t));
kenjiArai 0:5b88d5760320 191 if (temp_int) {
kenjiArai 0:5b88d5760320 192 region_ptr = (uint8_t *) region_ptr + (sizeof(ns_mem_word_size_t) - temp_int);
kenjiArai 0:5b88d5760320 193 region_size -= (sizeof(ns_mem_word_size_t) - temp_int);
kenjiArai 0:5b88d5760320 194 }
kenjiArai 0:5b88d5760320 195
kenjiArai 0:5b88d5760320 196 /* Make correction for total length */
kenjiArai 0:5b88d5760320 197 temp_int = (region_size % sizeof(ns_mem_word_size_t));
kenjiArai 0:5b88d5760320 198 if (temp_int) {
kenjiArai 0:5b88d5760320 199 region_size -= (sizeof(ns_mem_word_size_t) - temp_int);
kenjiArai 0:5b88d5760320 200 }
kenjiArai 0:5b88d5760320 201
kenjiArai 0:5b88d5760320 202 // Create hole from new heap memory
kenjiArai 0:5b88d5760320 203 temp_int = (region_size / sizeof(ns_mem_word_size_t));
kenjiArai 0:5b88d5760320 204 temp_int -= 2;
kenjiArai 0:5b88d5760320 205 block_ptr = region_ptr;
kenjiArai 0:5b88d5760320 206 *block_ptr = -(temp_int);
kenjiArai 0:5b88d5760320 207 block_ptr += (temp_int + 1); // now block_ptr points to end of block
kenjiArai 0:5b88d5760320 208 *block_ptr = -(temp_int);
kenjiArai 0:5b88d5760320 209
kenjiArai 0:5b88d5760320 210 // find place for the new hole from the holes list
kenjiArai 0:5b88d5760320 211 hole_t *hole_to_add = hole_from_block_start(region_ptr);
kenjiArai 0:5b88d5760320 212 hole_t *previous_hole = NULL;
kenjiArai 0:5b88d5760320 213 ns_list_foreach(hole_t, hole_in_list_ptr, &book->holes_list) {
kenjiArai 0:5b88d5760320 214 if (hole_in_list_ptr < hole_to_add) {
kenjiArai 0:5b88d5760320 215 previous_hole = hole_in_list_ptr;
kenjiArai 0:5b88d5760320 216 } else if (hole_in_list_ptr == hole_to_add) {
kenjiArai 0:5b88d5760320 217 // trying to add memory block that is already in the list!
kenjiArai 0:5b88d5760320 218 return -2;
kenjiArai 0:5b88d5760320 219 }
kenjiArai 0:5b88d5760320 220 }
kenjiArai 0:5b88d5760320 221
kenjiArai 0:5b88d5760320 222 // save region
kenjiArai 0:5b88d5760320 223 if (ns_dyn_mem_region_save(book, region_ptr, (region_size / (sizeof(ns_mem_word_size_t))) - 1) != 0) {
kenjiArai 0:5b88d5760320 224 return -3;
kenjiArai 0:5b88d5760320 225 }
kenjiArai 0:5b88d5760320 226
kenjiArai 0:5b88d5760320 227 // Add new hole to the list
kenjiArai 0:5b88d5760320 228 if (previous_hole) {
kenjiArai 0:5b88d5760320 229 ns_list_add_after(&book->holes_list, previous_hole, hole_to_add);
kenjiArai 0:5b88d5760320 230 } else {
kenjiArai 0:5b88d5760320 231 ns_list_add_to_start(&book->holes_list, hole_to_add);
kenjiArai 0:5b88d5760320 232 }
kenjiArai 0:5b88d5760320 233
kenjiArai 0:5b88d5760320 234 // adjust total heap size with new hole
kenjiArai 0:5b88d5760320 235 book->heap_size += region_size;
kenjiArai 0:5b88d5760320 236
kenjiArai 0:5b88d5760320 237 if (book->mem_stat_info_ptr) {
kenjiArai 0:5b88d5760320 238 book->mem_stat_info_ptr->heap_sector_size = book->heap_size;
kenjiArai 0:5b88d5760320 239 }
kenjiArai 0:5b88d5760320 240
kenjiArai 0:5b88d5760320 241 // adjust temporary allocation limits to match new heap
kenjiArai 0:5b88d5760320 242 book->temporary_alloc_heap_limit = book->heap_size / 100 * (100 - TEMPORARY_ALLOC_FREE_HEAP_THRESHOLD);
kenjiArai 0:5b88d5760320 243
kenjiArai 0:5b88d5760320 244 return 0;
kenjiArai 0:5b88d5760320 245 #else
kenjiArai 0:5b88d5760320 246 (void) book;
kenjiArai 0:5b88d5760320 247 (void) region_ptr;
kenjiArai 0:5b88d5760320 248 (void) region_size;
kenjiArai 0:5b88d5760320 249
kenjiArai 0:5b88d5760320 250 return -1;
kenjiArai 0:5b88d5760320 251 #endif
kenjiArai 0:5b88d5760320 252 }
kenjiArai 0:5b88d5760320 253
kenjiArai 0:5b88d5760320 254 const mem_stat_t *ns_mem_get_mem_stat(ns_mem_book_t *heap)
kenjiArai 0:5b88d5760320 255 {
kenjiArai 0:5b88d5760320 256 #ifndef STANDARD_MALLOC
kenjiArai 0:5b88d5760320 257 return heap->mem_stat_info_ptr;
kenjiArai 0:5b88d5760320 258 #else
kenjiArai 0:5b88d5760320 259 return NULL;
kenjiArai 0:5b88d5760320 260 #endif
kenjiArai 0:5b88d5760320 261 }
kenjiArai 0:5b88d5760320 262
kenjiArai 0:5b88d5760320 263 int ns_mem_set_temporary_alloc_free_heap_threshold(ns_mem_book_t *book, uint8_t free_heap_percentage, ns_mem_heap_size_t free_heap_amount)
kenjiArai 0:5b88d5760320 264 {
kenjiArai 0:5b88d5760320 265 #ifndef STANDARD_MALLOC
kenjiArai 0:5b88d5760320 266 ns_mem_heap_size_t heap_limit = 0;
kenjiArai 0:5b88d5760320 267
kenjiArai 0:5b88d5760320 268 if (!book || !book->mem_stat_info_ptr) {
kenjiArai 0:5b88d5760320 269 // no book or mem_stats
kenjiArai 0:5b88d5760320 270 return -1;
kenjiArai 0:5b88d5760320 271 }
kenjiArai 0:5b88d5760320 272
kenjiArai 0:5b88d5760320 273 if (free_heap_amount && free_heap_amount < book->heap_size / 2) {
kenjiArai 0:5b88d5760320 274 heap_limit = book->heap_size - free_heap_amount;
kenjiArai 0:5b88d5760320 275 }
kenjiArai 0:5b88d5760320 276
kenjiArai 0:5b88d5760320 277 if (!free_heap_amount && free_heap_percentage && free_heap_percentage < 50) {
kenjiArai 0:5b88d5760320 278 heap_limit = book->heap_size / 100 * (100 - free_heap_percentage);
kenjiArai 0:5b88d5760320 279 }
kenjiArai 0:5b88d5760320 280
kenjiArai 0:5b88d5760320 281 if (free_heap_amount == 0 && free_heap_percentage == 0) {
kenjiArai 0:5b88d5760320 282 // feature disabled, allow whole heap to be reserved by temporary allo
kenjiArai 0:5b88d5760320 283 heap_limit = book->heap_size;
kenjiArai 0:5b88d5760320 284 }
kenjiArai 0:5b88d5760320 285
kenjiArai 0:5b88d5760320 286 if (heap_limit == 0) {
kenjiArai 0:5b88d5760320 287 // illegal heap parameters
kenjiArai 0:5b88d5760320 288 return -2;
kenjiArai 0:5b88d5760320 289 }
kenjiArai 0:5b88d5760320 290
kenjiArai 0:5b88d5760320 291 book->temporary_alloc_heap_limit = heap_limit;
kenjiArai 0:5b88d5760320 292
kenjiArai 0:5b88d5760320 293 return 0;
kenjiArai 0:5b88d5760320 294 #else
kenjiArai 0:5b88d5760320 295 return -3;
kenjiArai 0:5b88d5760320 296 #endif
kenjiArai 0:5b88d5760320 297 }
kenjiArai 0:5b88d5760320 298
kenjiArai 0:5b88d5760320 299 extern int ns_dyn_mem_set_temporary_alloc_free_heap_threshold(uint8_t free_heap_percentage, ns_mem_heap_size_t free_heap_amount)
kenjiArai 0:5b88d5760320 300 {
kenjiArai 0:5b88d5760320 301 return ns_mem_set_temporary_alloc_free_heap_threshold(default_book, free_heap_percentage, free_heap_amount);
kenjiArai 0:5b88d5760320 302 }
kenjiArai 0:5b88d5760320 303
kenjiArai 0:5b88d5760320 304 #ifndef STANDARD_MALLOC
kenjiArai 0:5b88d5760320 305 static void dev_stat_update(mem_stat_t *mem_stat_info_ptr, mem_stat_update_t type, ns_mem_block_size_t size)
kenjiArai 0:5b88d5760320 306 {
kenjiArai 0:5b88d5760320 307 if (mem_stat_info_ptr) {
kenjiArai 0:5b88d5760320 308 switch (type) {
kenjiArai 0:5b88d5760320 309 case DEV_HEAP_ALLOC_OK:
kenjiArai 0:5b88d5760320 310 mem_stat_info_ptr->heap_sector_alloc_cnt++;
kenjiArai 0:5b88d5760320 311 mem_stat_info_ptr->heap_sector_allocated_bytes += size;
kenjiArai 0:5b88d5760320 312 if (mem_stat_info_ptr->heap_sector_allocated_bytes_max < mem_stat_info_ptr->heap_sector_allocated_bytes) {
kenjiArai 0:5b88d5760320 313 mem_stat_info_ptr->heap_sector_allocated_bytes_max = mem_stat_info_ptr->heap_sector_allocated_bytes;
kenjiArai 0:5b88d5760320 314 }
kenjiArai 0:5b88d5760320 315 mem_stat_info_ptr->heap_alloc_total_bytes += size;
kenjiArai 0:5b88d5760320 316 break;
kenjiArai 0:5b88d5760320 317 case DEV_HEAP_ALLOC_FAIL:
kenjiArai 0:5b88d5760320 318 mem_stat_info_ptr->heap_alloc_fail_cnt++;
kenjiArai 0:5b88d5760320 319 break;
kenjiArai 0:5b88d5760320 320 case DEV_HEAP_FREE:
kenjiArai 0:5b88d5760320 321 mem_stat_info_ptr->heap_sector_alloc_cnt--;
kenjiArai 0:5b88d5760320 322 mem_stat_info_ptr->heap_sector_allocated_bytes -= size;
kenjiArai 0:5b88d5760320 323 break;
kenjiArai 0:5b88d5760320 324 }
kenjiArai 0:5b88d5760320 325 }
kenjiArai 0:5b88d5760320 326 }
kenjiArai 0:5b88d5760320 327
kenjiArai 0:5b88d5760320 328 static ns_mem_word_size_t convert_allocation_size(ns_mem_book_t *book, ns_mem_block_size_t requested_bytes)
kenjiArai 0:5b88d5760320 329 {
kenjiArai 0:5b88d5760320 330 if (book->heap_main[0] == 0) {
kenjiArai 0:5b88d5760320 331 heap_failure(book, NS_DYN_MEM_HEAP_SECTOR_UNITIALIZED);
kenjiArai 0:5b88d5760320 332 } else if (requested_bytes < 1) {
kenjiArai 0:5b88d5760320 333 heap_failure(book, NS_DYN_MEM_ALLOCATE_SIZE_NOT_VALID);
kenjiArai 0:5b88d5760320 334 } else if (requested_bytes > (book->heap_size - 2 * sizeof(ns_mem_word_size_t))) {
kenjiArai 0:5b88d5760320 335 heap_failure(book, NS_DYN_MEM_ALLOCATE_SIZE_NOT_VALID);
kenjiArai 0:5b88d5760320 336 }
kenjiArai 0:5b88d5760320 337 return (requested_bytes + sizeof(ns_mem_word_size_t) - 1) / sizeof(ns_mem_word_size_t);
kenjiArai 0:5b88d5760320 338 }
kenjiArai 0:5b88d5760320 339
kenjiArai 0:5b88d5760320 340 // Checks that block length indicators are valid
kenjiArai 0:5b88d5760320 341 // Block has format: Size of data area [1 word] | data area [abs(size) words]| Size of data area [1 word]
kenjiArai 0:5b88d5760320 342 // If Size is negative it means area is unallocated
kenjiArai 0:5b88d5760320 343 static int8_t ns_mem_block_validate(ns_mem_word_size_t *block_start)
kenjiArai 0:5b88d5760320 344 {
kenjiArai 0:5b88d5760320 345 int8_t ret_val = -1;
kenjiArai 0:5b88d5760320 346 ns_mem_word_size_t *end = block_start;
kenjiArai 0:5b88d5760320 347 ns_mem_word_size_t size_start = *end;
kenjiArai 0:5b88d5760320 348 end += (1 + abs(size_start));
kenjiArai 0:5b88d5760320 349 if (size_start != 0 && size_start == *end) {
kenjiArai 0:5b88d5760320 350 ret_val = 0;
kenjiArai 0:5b88d5760320 351 }
kenjiArai 0:5b88d5760320 352 return ret_val;
kenjiArai 0:5b88d5760320 353 }
kenjiArai 0:5b88d5760320 354 #endif
kenjiArai 0:5b88d5760320 355
kenjiArai 0:5b88d5760320 356 // For direction, use 1 for direction up and -1 for down
kenjiArai 0:5b88d5760320 357 static void *ns_mem_internal_alloc(ns_mem_book_t *book, const ns_mem_block_size_t alloc_size, int direction)
kenjiArai 0:5b88d5760320 358 {
kenjiArai 0:5b88d5760320 359 #ifndef STANDARD_MALLOC
kenjiArai 0:5b88d5760320 360 if (!book) {
kenjiArai 0:5b88d5760320 361 /* We can not do anything except return NULL because we can't find book
kenjiArai 0:5b88d5760320 362 keeping block */
kenjiArai 0:5b88d5760320 363 return NULL;
kenjiArai 0:5b88d5760320 364 }
kenjiArai 0:5b88d5760320 365
kenjiArai 0:5b88d5760320 366 if (book->mem_stat_info_ptr && direction == 1) {
kenjiArai 0:5b88d5760320 367 if (book->mem_stat_info_ptr->heap_sector_allocated_bytes > book->temporary_alloc_heap_limit) {
kenjiArai 0:5b88d5760320 368 /* Not enough heap for temporary memory allocation */
kenjiArai 0:5b88d5760320 369 dev_stat_update(book->mem_stat_info_ptr, DEV_HEAP_ALLOC_FAIL, 0);
kenjiArai 0:5b88d5760320 370 return NULL;
kenjiArai 0:5b88d5760320 371 }
kenjiArai 0:5b88d5760320 372 }
kenjiArai 0:5b88d5760320 373
kenjiArai 0:5b88d5760320 374 ns_mem_word_size_t *block_ptr = NULL;
kenjiArai 0:5b88d5760320 375
kenjiArai 0:5b88d5760320 376 platform_enter_critical();
kenjiArai 0:5b88d5760320 377
kenjiArai 0:5b88d5760320 378 ns_mem_word_size_t data_size = convert_allocation_size(book, alloc_size);
kenjiArai 0:5b88d5760320 379 if (!data_size) {
kenjiArai 0:5b88d5760320 380 goto done;
kenjiArai 0:5b88d5760320 381 }
kenjiArai 0:5b88d5760320 382
kenjiArai 0:5b88d5760320 383 // ns_list_foreach, either forwards or backwards, result to ptr
kenjiArai 0:5b88d5760320 384 for (hole_t *cur_hole = direction > 0 ? ns_list_get_first(&book->holes_list)
kenjiArai 0:5b88d5760320 385 : ns_list_get_last(&book->holes_list);
kenjiArai 0:5b88d5760320 386 cur_hole;
kenjiArai 0:5b88d5760320 387 cur_hole = direction > 0 ? ns_list_get_next(&book->holes_list, cur_hole)
kenjiArai 0:5b88d5760320 388 : ns_list_get_previous(&book->holes_list, cur_hole)
kenjiArai 0:5b88d5760320 389 ) {
kenjiArai 0:5b88d5760320 390 ns_mem_word_size_t *p = block_start_from_hole(cur_hole);
kenjiArai 0:5b88d5760320 391 if (ns_mem_block_validate(p) != 0 || *p >= 0) {
kenjiArai 0:5b88d5760320 392 //Validation failed, or this supposed hole has positive (allocated) size
kenjiArai 0:5b88d5760320 393 heap_failure(book, NS_DYN_MEM_HEAP_SECTOR_CORRUPTED);
kenjiArai 0:5b88d5760320 394 break;
kenjiArai 0:5b88d5760320 395 }
kenjiArai 0:5b88d5760320 396 if (-*p >= data_size) {
kenjiArai 0:5b88d5760320 397 // Found a big enough block
kenjiArai 0:5b88d5760320 398 block_ptr = p;
kenjiArai 0:5b88d5760320 399 break;
kenjiArai 0:5b88d5760320 400 }
kenjiArai 0:5b88d5760320 401 }
kenjiArai 0:5b88d5760320 402
kenjiArai 0:5b88d5760320 403 if (!block_ptr) {
kenjiArai 0:5b88d5760320 404 goto done;
kenjiArai 0:5b88d5760320 405 }
kenjiArai 0:5b88d5760320 406
kenjiArai 0:5b88d5760320 407 // Separate declaration from initialization to keep IAR happy as the gotos skip this block.
kenjiArai 0:5b88d5760320 408 ns_mem_word_size_t block_data_size;
kenjiArai 0:5b88d5760320 409 block_data_size = -*block_ptr;
kenjiArai 0:5b88d5760320 410 if (block_data_size >= (data_size + 2 + HOLE_T_SIZE)) {
kenjiArai 0:5b88d5760320 411 ns_mem_word_size_t hole_size = block_data_size - data_size - 2;
kenjiArai 0:5b88d5760320 412 ns_mem_word_size_t *hole_ptr;
kenjiArai 0:5b88d5760320 413 //There is enough room for a new hole so create it first
kenjiArai 0:5b88d5760320 414 if (direction > 0) {
kenjiArai 0:5b88d5760320 415 hole_ptr = block_ptr + 1 + data_size + 1;
kenjiArai 0:5b88d5760320 416 // Hole will be left at end of area.
kenjiArai 0:5b88d5760320 417 // Would like to just replace this block_ptr with new descriptor, but
kenjiArai 0:5b88d5760320 418 // they could overlap, so ns_list_replace might fail
kenjiArai 0:5b88d5760320 419 //ns_list_replace(&holes_list, block_ptr, hole_from_block_start(hole_ptr));
kenjiArai 0:5b88d5760320 420 hole_t *before = ns_list_get_previous(&book->holes_list, hole_from_block_start(block_ptr));
kenjiArai 0:5b88d5760320 421 ns_list_remove(&book->holes_list, hole_from_block_start(block_ptr));
kenjiArai 0:5b88d5760320 422 if (before) {
kenjiArai 0:5b88d5760320 423 ns_list_add_after(&book->holes_list, before, hole_from_block_start(hole_ptr));
kenjiArai 0:5b88d5760320 424 } else {
kenjiArai 0:5b88d5760320 425 ns_list_add_to_start(&book->holes_list, hole_from_block_start(hole_ptr));
kenjiArai 0:5b88d5760320 426 }
kenjiArai 0:5b88d5760320 427 } else {
kenjiArai 0:5b88d5760320 428 hole_ptr = block_ptr;
kenjiArai 0:5b88d5760320 429 // Hole remains at start of area - keep existing descriptor in place.
kenjiArai 0:5b88d5760320 430 block_ptr += 1 + hole_size + 1;
kenjiArai 0:5b88d5760320 431 }
kenjiArai 0:5b88d5760320 432
kenjiArai 0:5b88d5760320 433 hole_ptr[0] = -hole_size;
kenjiArai 0:5b88d5760320 434 hole_ptr[1 + hole_size] = -hole_size;
kenjiArai 0:5b88d5760320 435 } else {
kenjiArai 0:5b88d5760320 436 // Not enough room for a left-over hole, so use the whole block
kenjiArai 0:5b88d5760320 437 data_size = block_data_size;
kenjiArai 0:5b88d5760320 438 ns_list_remove(&book->holes_list, hole_from_block_start(block_ptr));
kenjiArai 0:5b88d5760320 439 }
kenjiArai 0:5b88d5760320 440 block_ptr[0] = data_size;
kenjiArai 0:5b88d5760320 441 block_ptr[1 + data_size] = data_size;
kenjiArai 0:5b88d5760320 442
kenjiArai 0:5b88d5760320 443 done:
kenjiArai 0:5b88d5760320 444 if (book->mem_stat_info_ptr) {
kenjiArai 0:5b88d5760320 445 if (block_ptr) {
kenjiArai 0:5b88d5760320 446 //Update Allocate OK
kenjiArai 0:5b88d5760320 447 dev_stat_update(book->mem_stat_info_ptr, DEV_HEAP_ALLOC_OK, (data_size + 2) * sizeof(ns_mem_word_size_t));
kenjiArai 0:5b88d5760320 448 } else {
kenjiArai 0:5b88d5760320 449 //Update Allocate Fail, second parameter is used for stats
kenjiArai 0:5b88d5760320 450 dev_stat_update(book->mem_stat_info_ptr, DEV_HEAP_ALLOC_FAIL, 0);
kenjiArai 0:5b88d5760320 451 }
kenjiArai 0:5b88d5760320 452 }
kenjiArai 0:5b88d5760320 453 platform_exit_critical();
kenjiArai 0:5b88d5760320 454
kenjiArai 0:5b88d5760320 455 return block_ptr ? block_ptr + 1 : NULL;
kenjiArai 0:5b88d5760320 456 #else
kenjiArai 0:5b88d5760320 457 void *retval = NULL;
kenjiArai 0:5b88d5760320 458 if (alloc_size) {
kenjiArai 0:5b88d5760320 459 platform_enter_critical();
kenjiArai 0:5b88d5760320 460 retval = malloc(alloc_size);
kenjiArai 0:5b88d5760320 461 platform_exit_critical();
kenjiArai 0:5b88d5760320 462 }
kenjiArai 0:5b88d5760320 463 return retval;
kenjiArai 0:5b88d5760320 464 #endif
kenjiArai 0:5b88d5760320 465 }
kenjiArai 0:5b88d5760320 466
kenjiArai 0:5b88d5760320 467 void *ns_mem_alloc(ns_mem_book_t *heap, ns_mem_block_size_t alloc_size)
kenjiArai 0:5b88d5760320 468 {
kenjiArai 0:5b88d5760320 469 return ns_mem_internal_alloc(heap, alloc_size, -1);
kenjiArai 0:5b88d5760320 470 }
kenjiArai 0:5b88d5760320 471
kenjiArai 0:5b88d5760320 472 void *ns_mem_temporary_alloc(ns_mem_book_t *heap, ns_mem_block_size_t alloc_size)
kenjiArai 0:5b88d5760320 473 {
kenjiArai 0:5b88d5760320 474 return ns_mem_internal_alloc(heap, alloc_size, 1);
kenjiArai 0:5b88d5760320 475 }
kenjiArai 0:5b88d5760320 476
kenjiArai 0:5b88d5760320 477 void *ns_dyn_mem_alloc(ns_mem_block_size_t alloc_size)
kenjiArai 0:5b88d5760320 478 {
kenjiArai 0:5b88d5760320 479 return ns_mem_alloc(default_book, alloc_size);
kenjiArai 0:5b88d5760320 480 }
kenjiArai 0:5b88d5760320 481
kenjiArai 0:5b88d5760320 482 void *ns_dyn_mem_temporary_alloc(ns_mem_block_size_t alloc_size)
kenjiArai 0:5b88d5760320 483 {
kenjiArai 0:5b88d5760320 484 return ns_mem_temporary_alloc(default_book, alloc_size);
kenjiArai 0:5b88d5760320 485 }
kenjiArai 0:5b88d5760320 486
kenjiArai 0:5b88d5760320 487 #ifndef STANDARD_MALLOC
kenjiArai 0:5b88d5760320 488 static void ns_mem_free_and_merge_with_adjacent_blocks(ns_mem_book_t *book, ns_mem_word_size_t *cur_block, ns_mem_word_size_t data_size)
kenjiArai 0:5b88d5760320 489 {
kenjiArai 0:5b88d5760320 490 // Theory of operation: Block is always in form | Len | Data | Len |
kenjiArai 0:5b88d5760320 491 // So we need to check length of previous (if current not heap start)
kenjiArai 0:5b88d5760320 492 // and next (if current not heap end) blocks. Negative length means
kenjiArai 0:5b88d5760320 493 // free memory so we can merge freed block with those.
kenjiArai 0:5b88d5760320 494
kenjiArai 0:5b88d5760320 495 hole_t *existing_start = NULL;
kenjiArai 0:5b88d5760320 496 hole_t *existing_end = NULL;
kenjiArai 0:5b88d5760320 497 ns_mem_word_size_t *start = cur_block;
kenjiArai 0:5b88d5760320 498 ns_mem_word_size_t *end = cur_block + data_size + 1;
kenjiArai 0:5b88d5760320 499 ns_mem_word_size_t *region_start;
kenjiArai 0:5b88d5760320 500 ns_mem_word_size_t *region_end;
kenjiArai 0:5b88d5760320 501
kenjiArai 0:5b88d5760320 502 int region_index = ns_dyn_mem_region_find(book, cur_block, data_size);
kenjiArai 0:5b88d5760320 503 if (region_index >= 0) {
kenjiArai 0:5b88d5760320 504 region_start = book->heap_main[region_index];
kenjiArai 0:5b88d5760320 505 region_end = book->heap_main_end[region_index];
kenjiArai 0:5b88d5760320 506 } else {
kenjiArai 0:5b88d5760320 507 heap_failure(book, NS_DYN_MEM_HEAP_SECTOR_CORRUPTED);
kenjiArai 0:5b88d5760320 508 // can't find region for the block, return
kenjiArai 0:5b88d5760320 509 return;
kenjiArai 0:5b88d5760320 510 }
kenjiArai 0:5b88d5760320 511
kenjiArai 0:5b88d5760320 512 //invalidate current block
kenjiArai 0:5b88d5760320 513 *start = -data_size;
kenjiArai 0:5b88d5760320 514 *end = -data_size;
kenjiArai 0:5b88d5760320 515 ns_mem_word_size_t merged_data_size = data_size;
kenjiArai 0:5b88d5760320 516
kenjiArai 0:5b88d5760320 517 if (start != region_start) {
kenjiArai 0:5b88d5760320 518 if (*(start - 1) < 0) {
kenjiArai 0:5b88d5760320 519 ns_mem_word_size_t *block_end = start - 1;
kenjiArai 0:5b88d5760320 520 ns_mem_word_size_t block_size = 1 + (-*block_end) + 1;
kenjiArai 0:5b88d5760320 521 merged_data_size += block_size;
kenjiArai 0:5b88d5760320 522 start -= block_size;
kenjiArai 0:5b88d5760320 523 if (*start != *block_end) {
kenjiArai 0:5b88d5760320 524 heap_failure(book, NS_DYN_MEM_HEAP_SECTOR_CORRUPTED);
kenjiArai 0:5b88d5760320 525 }
kenjiArai 0:5b88d5760320 526 if (block_size >= 1 + HOLE_T_SIZE + 1) {
kenjiArai 0:5b88d5760320 527 existing_start = hole_from_block_start(start);
kenjiArai 0:5b88d5760320 528 }
kenjiArai 0:5b88d5760320 529 }
kenjiArai 0:5b88d5760320 530 }
kenjiArai 0:5b88d5760320 531
kenjiArai 0:5b88d5760320 532 if (end != region_end) {
kenjiArai 0:5b88d5760320 533 if (*(end + 1) < 0) {
kenjiArai 0:5b88d5760320 534 ns_mem_word_size_t *block_start = end + 1;
kenjiArai 0:5b88d5760320 535 ns_mem_word_size_t block_size = 1 + (-*block_start) + 1;
kenjiArai 0:5b88d5760320 536 merged_data_size += block_size;
kenjiArai 0:5b88d5760320 537 end += block_size;
kenjiArai 0:5b88d5760320 538 if (*end != *block_start) {
kenjiArai 0:5b88d5760320 539 heap_failure(book, NS_DYN_MEM_HEAP_SECTOR_CORRUPTED);
kenjiArai 0:5b88d5760320 540 }
kenjiArai 0:5b88d5760320 541 if (block_size >= 1 + HOLE_T_SIZE + 1) {
kenjiArai 0:5b88d5760320 542 existing_end = hole_from_block_start(block_start);
kenjiArai 0:5b88d5760320 543 }
kenjiArai 0:5b88d5760320 544 }
kenjiArai 0:5b88d5760320 545 }
kenjiArai 0:5b88d5760320 546
kenjiArai 0:5b88d5760320 547 hole_t *to_add = hole_from_block_start(start);
kenjiArai 0:5b88d5760320 548 hole_t *before = NULL;
kenjiArai 0:5b88d5760320 549 if (existing_end) {
kenjiArai 0:5b88d5760320 550 // Extending hole described by "existing_end" downwards.
kenjiArai 0:5b88d5760320 551 // Will replace with descriptor at bottom of merged block.
kenjiArai 0:5b88d5760320 552 // (Can't use ns_list_replace, because of danger of overlap)
kenjiArai 0:5b88d5760320 553 // Optimisation - note our position for insertion below.
kenjiArai 0:5b88d5760320 554 before = ns_list_get_next(&book->holes_list, existing_end);
kenjiArai 0:5b88d5760320 555 ns_list_remove(&book->holes_list, existing_end);
kenjiArai 0:5b88d5760320 556 }
kenjiArai 0:5b88d5760320 557 if (existing_start) {
kenjiArai 0:5b88d5760320 558 // Extending hole described by "existing_start" upwards.
kenjiArai 0:5b88d5760320 559 // No need to modify that descriptor - it remains at the bottom
kenjiArai 0:5b88d5760320 560 // of the merged block to describe it.
kenjiArai 0:5b88d5760320 561 } else {
kenjiArai 0:5b88d5760320 562 // Didn't find adjacent descriptors, but may still
kenjiArai 0:5b88d5760320 563 // be merging with small blocks without descriptors.
kenjiArai 0:5b88d5760320 564 if (merged_data_size >= HOLE_T_SIZE) {
kenjiArai 0:5b88d5760320 565 // Locate hole position in list, if we don't already know
kenjiArai 0:5b88d5760320 566 // from merging with the block above.
kenjiArai 0:5b88d5760320 567 if (!existing_end) {
kenjiArai 0:5b88d5760320 568 ns_list_foreach(hole_t, ptr, &book->holes_list) {
kenjiArai 0:5b88d5760320 569 if (ptr > to_add) {
kenjiArai 0:5b88d5760320 570 before = ptr;
kenjiArai 0:5b88d5760320 571 break;
kenjiArai 0:5b88d5760320 572 }
kenjiArai 0:5b88d5760320 573 }
kenjiArai 0:5b88d5760320 574 }
kenjiArai 0:5b88d5760320 575 if (before) {
kenjiArai 0:5b88d5760320 576 ns_list_add_before(&book->holes_list, before, to_add);
kenjiArai 0:5b88d5760320 577 } else {
kenjiArai 0:5b88d5760320 578 ns_list_add_to_end(&book->holes_list, to_add);
kenjiArai 0:5b88d5760320 579 }
kenjiArai 0:5b88d5760320 580
kenjiArai 0:5b88d5760320 581 }
kenjiArai 0:5b88d5760320 582 }
kenjiArai 0:5b88d5760320 583 *start = -merged_data_size;
kenjiArai 0:5b88d5760320 584 *end = -merged_data_size;
kenjiArai 0:5b88d5760320 585 }
kenjiArai 0:5b88d5760320 586 #endif
kenjiArai 0:5b88d5760320 587
kenjiArai 0:5b88d5760320 588 static bool pointer_address_validate(ns_mem_book_t *book, ns_mem_word_size_t *ptr, ns_mem_word_size_t size)
kenjiArai 0:5b88d5760320 589 {
kenjiArai 0:5b88d5760320 590
kenjiArai 0:5b88d5760320 591 if (ns_dyn_mem_region_find(book, ptr, size) >= 0) {
kenjiArai 0:5b88d5760320 592 return true;
kenjiArai 0:5b88d5760320 593 }
kenjiArai 0:5b88d5760320 594
kenjiArai 0:5b88d5760320 595 return false;
kenjiArai 0:5b88d5760320 596 }
kenjiArai 0:5b88d5760320 597
kenjiArai 0:5b88d5760320 598 void ns_mem_free(ns_mem_book_t *book, void *block)
kenjiArai 0:5b88d5760320 599 {
kenjiArai 0:5b88d5760320 600 #ifndef STANDARD_MALLOC
kenjiArai 0:5b88d5760320 601
kenjiArai 0:5b88d5760320 602 if (!block) {
kenjiArai 0:5b88d5760320 603 return;
kenjiArai 0:5b88d5760320 604 }
kenjiArai 0:5b88d5760320 605
kenjiArai 0:5b88d5760320 606 ns_mem_word_size_t *ptr = block;
kenjiArai 0:5b88d5760320 607 ns_mem_word_size_t size;
kenjiArai 0:5b88d5760320 608
kenjiArai 0:5b88d5760320 609 platform_enter_critical();
kenjiArai 0:5b88d5760320 610 ptr --;
kenjiArai 0:5b88d5760320 611 //Read Current Size
kenjiArai 0:5b88d5760320 612 size = *ptr;
kenjiArai 0:5b88d5760320 613 if (!pointer_address_validate(book, ptr, size)) {
kenjiArai 0:5b88d5760320 614 heap_failure(book, NS_DYN_MEM_POINTER_NOT_VALID);
kenjiArai 0:5b88d5760320 615 } else if (size < 0) {
kenjiArai 0:5b88d5760320 616 heap_failure(book, NS_DYN_MEM_DOUBLE_FREE);
kenjiArai 0:5b88d5760320 617 } else {
kenjiArai 0:5b88d5760320 618 if (ns_mem_block_validate(ptr) != 0) {
kenjiArai 0:5b88d5760320 619 heap_failure(book, NS_DYN_MEM_HEAP_SECTOR_CORRUPTED);
kenjiArai 0:5b88d5760320 620 } else {
kenjiArai 0:5b88d5760320 621 ns_mem_free_and_merge_with_adjacent_blocks(book, ptr, size);
kenjiArai 0:5b88d5760320 622 if (book->mem_stat_info_ptr) {
kenjiArai 0:5b88d5760320 623 //Update Free Counter
kenjiArai 0:5b88d5760320 624 dev_stat_update(book->mem_stat_info_ptr, DEV_HEAP_FREE, (size + 2) * sizeof(ns_mem_word_size_t));
kenjiArai 0:5b88d5760320 625 }
kenjiArai 0:5b88d5760320 626 }
kenjiArai 0:5b88d5760320 627 }
kenjiArai 0:5b88d5760320 628
kenjiArai 0:5b88d5760320 629 platform_exit_critical();
kenjiArai 0:5b88d5760320 630 #else
kenjiArai 0:5b88d5760320 631 platform_enter_critical();
kenjiArai 0:5b88d5760320 632 free(block);
kenjiArai 0:5b88d5760320 633 platform_exit_critical();
kenjiArai 0:5b88d5760320 634 #endif
kenjiArai 0:5b88d5760320 635 }
kenjiArai 0:5b88d5760320 636
kenjiArai 0:5b88d5760320 637 void ns_dyn_mem_free(void *block)
kenjiArai 0:5b88d5760320 638 {
kenjiArai 0:5b88d5760320 639 ns_mem_free(default_book, block);
kenjiArai 0:5b88d5760320 640 }