WORKS

Dependencies:   MAX44000 PWM_Tone_Library nexpaq_mdk

Fork of LED_Demo by Maxim nexpaq

Committer:
cyberjoey
Date:
Sat Oct 22 01:31:58 2016 +0000
Revision:
9:6bb35cef007d
Parent:
1:55a6170b404f
WORKING

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nexpaq 1:55a6170b404f 1 /*
nexpaq 1:55a6170b404f 2 * Copyright (c) 2014-2015 ARM Limited. All rights reserved.
nexpaq 1:55a6170b404f 3 * SPDX-License-Identifier: Apache-2.0
nexpaq 1:55a6170b404f 4 * Licensed under the Apache License, Version 2.0 (the License); you may
nexpaq 1:55a6170b404f 5 * not use this file except in compliance with the License.
nexpaq 1:55a6170b404f 6 * You may obtain a copy of the License at
nexpaq 1:55a6170b404f 7 *
nexpaq 1:55a6170b404f 8 * http://www.apache.org/licenses/LICENSE-2.0
nexpaq 1:55a6170b404f 9 *
nexpaq 1:55a6170b404f 10 * Unless required by applicable law or agreed to in writing, software
nexpaq 1:55a6170b404f 11 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
nexpaq 1:55a6170b404f 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
nexpaq 1:55a6170b404f 13 * See the License for the specific language governing permissions and
nexpaq 1:55a6170b404f 14 * limitations under the License.
nexpaq 1:55a6170b404f 15 */
nexpaq 1:55a6170b404f 16 #include <stdint.h>
nexpaq 1:55a6170b404f 17 #include <string.h>
nexpaq 1:55a6170b404f 18 #include "nsdynmemLIB.h"
nexpaq 1:55a6170b404f 19 #include "platform/arm_hal_interrupt.h"
nexpaq 1:55a6170b404f 20 #include <stdlib.h>
nexpaq 1:55a6170b404f 21 #include "ns_list.h"
nexpaq 1:55a6170b404f 22
nexpaq 1:55a6170b404f 23 void (*heap_failure_callback)(heap_fail_t);
nexpaq 1:55a6170b404f 24
nexpaq 1:55a6170b404f 25 #ifndef STANDARD_MALLOC
nexpaq 1:55a6170b404f 26 static int *heap_main = 0;
nexpaq 1:55a6170b404f 27 static int *heap_main_end = 0;
nexpaq 1:55a6170b404f 28 static uint16_t heap_size = 0;
nexpaq 1:55a6170b404f 29
nexpaq 1:55a6170b404f 30 typedef enum mem_stat_update_t {
nexpaq 1:55a6170b404f 31 DEV_HEAP_ALLOC_OK,
nexpaq 1:55a6170b404f 32 DEV_HEAP_ALLOC_FAIL,
nexpaq 1:55a6170b404f 33 DEV_HEAP_FREE,
nexpaq 1:55a6170b404f 34 } mem_stat_update_t;
nexpaq 1:55a6170b404f 35
nexpaq 1:55a6170b404f 36
nexpaq 1:55a6170b404f 37 static mem_stat_t *mem_stat_info_ptr = 0;
nexpaq 1:55a6170b404f 38
nexpaq 1:55a6170b404f 39 typedef struct {
nexpaq 1:55a6170b404f 40 ns_list_link_t link;
nexpaq 1:55a6170b404f 41 } hole_t;
nexpaq 1:55a6170b404f 42
nexpaq 1:55a6170b404f 43 static NS_LIST_DEFINE(holes_list, hole_t, link);
nexpaq 1:55a6170b404f 44
nexpaq 1:55a6170b404f 45 // size of a hole_t in our word units
nexpaq 1:55a6170b404f 46 #define HOLE_T_SIZE ((sizeof(hole_t) + sizeof(int) - 1) / sizeof(int))
nexpaq 1:55a6170b404f 47
nexpaq 1:55a6170b404f 48 static NS_INLINE hole_t *hole_from_block_start(int *start)
nexpaq 1:55a6170b404f 49 {
nexpaq 1:55a6170b404f 50 return (hole_t *)(start + 1);
nexpaq 1:55a6170b404f 51 }
nexpaq 1:55a6170b404f 52
nexpaq 1:55a6170b404f 53 static NS_INLINE int *block_start_from_hole(hole_t *start)
nexpaq 1:55a6170b404f 54 {
nexpaq 1:55a6170b404f 55 return ((int *)start) - 1;
nexpaq 1:55a6170b404f 56 }
nexpaq 1:55a6170b404f 57
nexpaq 1:55a6170b404f 58
nexpaq 1:55a6170b404f 59 static void heap_failure(heap_fail_t reason)
nexpaq 1:55a6170b404f 60 {
nexpaq 1:55a6170b404f 61 if (heap_failure_callback) {
nexpaq 1:55a6170b404f 62 heap_failure_callback(reason);
nexpaq 1:55a6170b404f 63 }
nexpaq 1:55a6170b404f 64 }
nexpaq 1:55a6170b404f 65
nexpaq 1:55a6170b404f 66 #endif
nexpaq 1:55a6170b404f 67
nexpaq 1:55a6170b404f 68 void ns_dyn_mem_init(uint8_t *heap, uint16_t h_size, void (*passed_fptr)(heap_fail_t), mem_stat_t *info_ptr)
nexpaq 1:55a6170b404f 69 {
nexpaq 1:55a6170b404f 70 #ifndef STANDARD_MALLOC
nexpaq 1:55a6170b404f 71 int *ptr;
nexpaq 1:55a6170b404f 72 int temp_int;
nexpaq 1:55a6170b404f 73 /* Do memory alignment */
nexpaq 1:55a6170b404f 74 temp_int = ((uintptr_t)heap % sizeof(int));
nexpaq 1:55a6170b404f 75 if (temp_int) {
nexpaq 1:55a6170b404f 76 heap += (sizeof(int) - temp_int);
nexpaq 1:55a6170b404f 77 h_size -= (sizeof(int) - temp_int);
nexpaq 1:55a6170b404f 78 }
nexpaq 1:55a6170b404f 79
nexpaq 1:55a6170b404f 80 /* Make correction for total length also */
nexpaq 1:55a6170b404f 81 temp_int = (h_size % sizeof(int));
nexpaq 1:55a6170b404f 82 if (temp_int) {
nexpaq 1:55a6170b404f 83 h_size -= (sizeof(int) - temp_int);
nexpaq 1:55a6170b404f 84 }
nexpaq 1:55a6170b404f 85 heap_main = (int *)heap; // SET Heap Pointer
nexpaq 1:55a6170b404f 86 heap_size = h_size; //Set Heap Size
nexpaq 1:55a6170b404f 87 temp_int = (h_size / sizeof(int));
nexpaq 1:55a6170b404f 88 temp_int -= 2;
nexpaq 1:55a6170b404f 89 ptr = heap_main;
nexpaq 1:55a6170b404f 90 *ptr = -(temp_int);
nexpaq 1:55a6170b404f 91 ptr += (temp_int + 1);
nexpaq 1:55a6170b404f 92 *ptr = -(temp_int);
nexpaq 1:55a6170b404f 93 heap_main_end = ptr;
nexpaq 1:55a6170b404f 94
nexpaq 1:55a6170b404f 95 ns_list_init(&holes_list);
nexpaq 1:55a6170b404f 96 ns_list_add_to_start(&holes_list, hole_from_block_start(heap_main));
nexpaq 1:55a6170b404f 97
nexpaq 1:55a6170b404f 98 //RESET Memory by Hea Len
nexpaq 1:55a6170b404f 99 if (info_ptr) {
nexpaq 1:55a6170b404f 100 mem_stat_info_ptr = info_ptr;
nexpaq 1:55a6170b404f 101 memset(mem_stat_info_ptr, 0, sizeof(mem_stat_t));
nexpaq 1:55a6170b404f 102 mem_stat_info_ptr->heap_sector_size = heap_size;
nexpaq 1:55a6170b404f 103 }
nexpaq 1:55a6170b404f 104 #endif
nexpaq 1:55a6170b404f 105 heap_failure_callback = passed_fptr;
nexpaq 1:55a6170b404f 106 }
nexpaq 1:55a6170b404f 107
nexpaq 1:55a6170b404f 108 const mem_stat_t *ns_dyn_mem_get_mem_stat(void)
nexpaq 1:55a6170b404f 109 {
nexpaq 1:55a6170b404f 110 #ifndef STANDARD_MALLOC
nexpaq 1:55a6170b404f 111 return mem_stat_info_ptr;
nexpaq 1:55a6170b404f 112 #else
nexpaq 1:55a6170b404f 113 return NULL;
nexpaq 1:55a6170b404f 114 #endif
nexpaq 1:55a6170b404f 115 }
nexpaq 1:55a6170b404f 116
nexpaq 1:55a6170b404f 117 #ifndef STANDARD_MALLOC
nexpaq 1:55a6170b404f 118 void dev_stat_update(mem_stat_update_t type, int16_t size)
nexpaq 1:55a6170b404f 119 {
nexpaq 1:55a6170b404f 120 if (mem_stat_info_ptr) {
nexpaq 1:55a6170b404f 121 switch (type) {
nexpaq 1:55a6170b404f 122 case DEV_HEAP_ALLOC_OK:
nexpaq 1:55a6170b404f 123 mem_stat_info_ptr->heap_sector_alloc_cnt++;
nexpaq 1:55a6170b404f 124 mem_stat_info_ptr->heap_sector_allocated_bytes += size;
nexpaq 1:55a6170b404f 125 if (mem_stat_info_ptr->heap_sector_allocated_bytes_max < mem_stat_info_ptr->heap_sector_allocated_bytes) {
nexpaq 1:55a6170b404f 126 mem_stat_info_ptr->heap_sector_allocated_bytes_max = mem_stat_info_ptr->heap_sector_allocated_bytes;
nexpaq 1:55a6170b404f 127 }
nexpaq 1:55a6170b404f 128 mem_stat_info_ptr->heap_alloc_total_bytes += size;
nexpaq 1:55a6170b404f 129 break;
nexpaq 1:55a6170b404f 130 case DEV_HEAP_ALLOC_FAIL:
nexpaq 1:55a6170b404f 131 mem_stat_info_ptr->heap_alloc_fail_cnt++;
nexpaq 1:55a6170b404f 132 break;
nexpaq 1:55a6170b404f 133 case DEV_HEAP_FREE:
nexpaq 1:55a6170b404f 134 mem_stat_info_ptr->heap_sector_alloc_cnt--;
nexpaq 1:55a6170b404f 135 mem_stat_info_ptr->heap_sector_allocated_bytes -= size;
nexpaq 1:55a6170b404f 136 break;
nexpaq 1:55a6170b404f 137 }
nexpaq 1:55a6170b404f 138 }
nexpaq 1:55a6170b404f 139 }
nexpaq 1:55a6170b404f 140
nexpaq 1:55a6170b404f 141 static int convert_allocation_size(int16_t requested_bytes)
nexpaq 1:55a6170b404f 142 {
nexpaq 1:55a6170b404f 143 if (heap_main == 0) {
nexpaq 1:55a6170b404f 144 heap_failure(NS_DYN_MEM_HEAP_SECTOR_UNITIALIZED);
nexpaq 1:55a6170b404f 145 } else if (requested_bytes < 1) {
nexpaq 1:55a6170b404f 146 heap_failure(NS_DYN_MEM_ALLOCATE_SIZE_NOT_VALID);
nexpaq 1:55a6170b404f 147 } else if (requested_bytes > (heap_size - 2 * sizeof(int)) ) {
nexpaq 1:55a6170b404f 148 heap_failure(NS_DYN_MEM_ALLOCATE_SIZE_NOT_VALID);
nexpaq 1:55a6170b404f 149 }
nexpaq 1:55a6170b404f 150 return (requested_bytes + sizeof(int) - 1) / sizeof(int);
nexpaq 1:55a6170b404f 151 }
nexpaq 1:55a6170b404f 152
nexpaq 1:55a6170b404f 153 // Checks that block length indicators are valid
nexpaq 1:55a6170b404f 154 // Block has format: Size of data area [1 word] | data area [abs(size) words]| Size of data area [1 word]
nexpaq 1:55a6170b404f 155 // If Size is negative it means area is unallocated
nexpaq 1:55a6170b404f 156 // For direction, use 1 for direction up and -1 for down
nexpaq 1:55a6170b404f 157 static int8_t ns_block_validate(int *block_start, int direction)
nexpaq 1:55a6170b404f 158 {
nexpaq 1:55a6170b404f 159 int8_t ret_val = -1;
nexpaq 1:55a6170b404f 160 int *end = block_start;
nexpaq 1:55a6170b404f 161 int size_start = *end;
nexpaq 1:55a6170b404f 162 end += (1 + abs(size_start));
nexpaq 1:55a6170b404f 163 if (size_start != 0 && size_start == *end) {
nexpaq 1:55a6170b404f 164 ret_val = 0;
nexpaq 1:55a6170b404f 165 }
nexpaq 1:55a6170b404f 166 return ret_val;
nexpaq 1:55a6170b404f 167 }
nexpaq 1:55a6170b404f 168 #endif
nexpaq 1:55a6170b404f 169
nexpaq 1:55a6170b404f 170 // For direction, use 1 for direction up and -1 for down
nexpaq 1:55a6170b404f 171 static void *ns_dyn_mem_internal_alloc(const int16_t alloc_size, int direction)
nexpaq 1:55a6170b404f 172 {
nexpaq 1:55a6170b404f 173 #ifndef STANDARD_MALLOC
nexpaq 1:55a6170b404f 174 int *block_ptr = NULL;
nexpaq 1:55a6170b404f 175
nexpaq 1:55a6170b404f 176 platform_enter_critical();
nexpaq 1:55a6170b404f 177
nexpaq 1:55a6170b404f 178 int data_size = convert_allocation_size(alloc_size);
nexpaq 1:55a6170b404f 179 if (!data_size) {
nexpaq 1:55a6170b404f 180 goto done;
nexpaq 1:55a6170b404f 181 }
nexpaq 1:55a6170b404f 182
nexpaq 1:55a6170b404f 183 // ns_list_foreach, either forwards or backwards, result to ptr
nexpaq 1:55a6170b404f 184 for (hole_t *cur_hole = direction > 0 ? ns_list_get_first(&holes_list)
nexpaq 1:55a6170b404f 185 : ns_list_get_last(&holes_list);
nexpaq 1:55a6170b404f 186 cur_hole;
nexpaq 1:55a6170b404f 187 cur_hole = direction > 0 ? ns_list_get_next(&holes_list, cur_hole)
nexpaq 1:55a6170b404f 188 : ns_list_get_previous(&holes_list, cur_hole)
nexpaq 1:55a6170b404f 189 ) {
nexpaq 1:55a6170b404f 190 int *p = block_start_from_hole(cur_hole);
nexpaq 1:55a6170b404f 191 if (ns_block_validate(p, direction) != 0 || *p >= 0) {
nexpaq 1:55a6170b404f 192 //Validation failed, or this supposed hole has positive (allocated) size
nexpaq 1:55a6170b404f 193 heap_failure(NS_DYN_MEM_HEAP_SECTOR_CORRUPTED);
nexpaq 1:55a6170b404f 194 break;
nexpaq 1:55a6170b404f 195 }
nexpaq 1:55a6170b404f 196 if (-*p >= data_size) {
nexpaq 1:55a6170b404f 197 // Found a big enough block
nexpaq 1:55a6170b404f 198 block_ptr = p;
nexpaq 1:55a6170b404f 199 break;
nexpaq 1:55a6170b404f 200 }
nexpaq 1:55a6170b404f 201 }
nexpaq 1:55a6170b404f 202
nexpaq 1:55a6170b404f 203 if (!block_ptr) {
nexpaq 1:55a6170b404f 204 goto done;
nexpaq 1:55a6170b404f 205 }
nexpaq 1:55a6170b404f 206
nexpaq 1:55a6170b404f 207 int block_data_size = -*block_ptr;
nexpaq 1:55a6170b404f 208 if (block_data_size >= (data_size + 2 + HOLE_T_SIZE)) {
nexpaq 1:55a6170b404f 209 int hole_size = block_data_size - data_size - 2;
nexpaq 1:55a6170b404f 210 int *hole_ptr;
nexpaq 1:55a6170b404f 211 //There is enough room for a new hole so create it first
nexpaq 1:55a6170b404f 212 if ( direction > 0 ) {
nexpaq 1:55a6170b404f 213 hole_ptr = block_ptr + 1 + data_size + 1;
nexpaq 1:55a6170b404f 214 // Hole will be left at end of area.
nexpaq 1:55a6170b404f 215 // Would like to just replace this block_ptr with new descriptor, but
nexpaq 1:55a6170b404f 216 // they could overlap, so ns_list_replace might fail
nexpaq 1:55a6170b404f 217 //ns_list_replace(&holes_list, block_ptr, hole_from_block_start(hole_ptr));
nexpaq 1:55a6170b404f 218 hole_t *before = ns_list_get_previous(&holes_list, hole_from_block_start(block_ptr));
nexpaq 1:55a6170b404f 219 ns_list_remove(&holes_list, hole_from_block_start(block_ptr));
nexpaq 1:55a6170b404f 220 if (before) {
nexpaq 1:55a6170b404f 221 ns_list_add_after(&holes_list, before, hole_from_block_start(hole_ptr));
nexpaq 1:55a6170b404f 222 } else {
nexpaq 1:55a6170b404f 223 ns_list_add_to_start(&holes_list, hole_from_block_start(hole_ptr));
nexpaq 1:55a6170b404f 224 }
nexpaq 1:55a6170b404f 225 } else {
nexpaq 1:55a6170b404f 226 hole_ptr = block_ptr;
nexpaq 1:55a6170b404f 227 // Hole remains at start of area - keep existing descriptor in place.
nexpaq 1:55a6170b404f 228 block_ptr += 1 + hole_size + 1;
nexpaq 1:55a6170b404f 229 }
nexpaq 1:55a6170b404f 230
nexpaq 1:55a6170b404f 231 hole_ptr[0] = -hole_size;
nexpaq 1:55a6170b404f 232 hole_ptr[1 + hole_size] = -hole_size;
nexpaq 1:55a6170b404f 233 } else {
nexpaq 1:55a6170b404f 234 // Not enough room for a left-over hole, so use the whole block
nexpaq 1:55a6170b404f 235 data_size = block_data_size;
nexpaq 1:55a6170b404f 236 ns_list_remove(&holes_list, hole_from_block_start(block_ptr));
nexpaq 1:55a6170b404f 237 }
nexpaq 1:55a6170b404f 238 block_ptr[0] = data_size;
nexpaq 1:55a6170b404f 239 block_ptr[1 + data_size] = data_size;
nexpaq 1:55a6170b404f 240
nexpaq 1:55a6170b404f 241 done:
nexpaq 1:55a6170b404f 242 if (mem_stat_info_ptr) {
nexpaq 1:55a6170b404f 243 if (block_ptr) {
nexpaq 1:55a6170b404f 244 //Update Allocate OK
nexpaq 1:55a6170b404f 245 dev_stat_update(DEV_HEAP_ALLOC_OK, (data_size + 2) * sizeof(int));
nexpaq 1:55a6170b404f 246
nexpaq 1:55a6170b404f 247 } else {
nexpaq 1:55a6170b404f 248 //Update Allocate Fail, second parameter is not used for stats
nexpaq 1:55a6170b404f 249 dev_stat_update(DEV_HEAP_ALLOC_FAIL, 0);
nexpaq 1:55a6170b404f 250 }
nexpaq 1:55a6170b404f 251 }
nexpaq 1:55a6170b404f 252 platform_exit_critical();
nexpaq 1:55a6170b404f 253
nexpaq 1:55a6170b404f 254 return block_ptr ? block_ptr + 1 : NULL;
nexpaq 1:55a6170b404f 255 #else
nexpaq 1:55a6170b404f 256 void *retval = NULL;
nexpaq 1:55a6170b404f 257 if (alloc_size) {
nexpaq 1:55a6170b404f 258 platform_enter_critical();
nexpaq 1:55a6170b404f 259 retval = malloc(alloc_size);
nexpaq 1:55a6170b404f 260 platform_exit_critical();
nexpaq 1:55a6170b404f 261 }
nexpaq 1:55a6170b404f 262 return retval;
nexpaq 1:55a6170b404f 263 #endif
nexpaq 1:55a6170b404f 264 }
nexpaq 1:55a6170b404f 265
nexpaq 1:55a6170b404f 266 void *ns_dyn_mem_alloc(int16_t alloc_size)
nexpaq 1:55a6170b404f 267 {
nexpaq 1:55a6170b404f 268 return ns_dyn_mem_internal_alloc(alloc_size, -1);
nexpaq 1:55a6170b404f 269 }
nexpaq 1:55a6170b404f 270
nexpaq 1:55a6170b404f 271 void *ns_dyn_mem_temporary_alloc(int16_t alloc_size)
nexpaq 1:55a6170b404f 272 {
nexpaq 1:55a6170b404f 273 return ns_dyn_mem_internal_alloc(alloc_size, 1);
nexpaq 1:55a6170b404f 274 }
nexpaq 1:55a6170b404f 275
nexpaq 1:55a6170b404f 276 #ifndef STANDARD_MALLOC
nexpaq 1:55a6170b404f 277 static void ns_free_and_merge_with_adjacent_blocks(int *cur_block, int data_size)
nexpaq 1:55a6170b404f 278 {
nexpaq 1:55a6170b404f 279 // Theory of operation: Block is always in form | Len | Data | Len |
nexpaq 1:55a6170b404f 280 // So we need to check length of previous (if current not heap start)
nexpaq 1:55a6170b404f 281 // and next (if current not heap end) blocks. Negative length means
nexpaq 1:55a6170b404f 282 // free memory so we can merge freed block with those.
nexpaq 1:55a6170b404f 283
nexpaq 1:55a6170b404f 284 hole_t *existing_start = NULL;
nexpaq 1:55a6170b404f 285 hole_t *existing_end = NULL;
nexpaq 1:55a6170b404f 286 int *start = cur_block;
nexpaq 1:55a6170b404f 287 int *end = cur_block + data_size + 1;
nexpaq 1:55a6170b404f 288 //invalidate current block
nexpaq 1:55a6170b404f 289 *cur_block = -data_size;
nexpaq 1:55a6170b404f 290 *end = -data_size;
nexpaq 1:55a6170b404f 291 int merged_data_size = data_size;
nexpaq 1:55a6170b404f 292
nexpaq 1:55a6170b404f 293 if (cur_block != heap_main) {
nexpaq 1:55a6170b404f 294 cur_block--;
nexpaq 1:55a6170b404f 295 if (*cur_block < 0) {
nexpaq 1:55a6170b404f 296 merged_data_size += (2 - *cur_block);
nexpaq 1:55a6170b404f 297 start -= (2 - *cur_block);
nexpaq 1:55a6170b404f 298 if (-*start >= HOLE_T_SIZE) {
nexpaq 1:55a6170b404f 299 existing_start = hole_from_block_start(start);
nexpaq 1:55a6170b404f 300 }
nexpaq 1:55a6170b404f 301 }
nexpaq 1:55a6170b404f 302 cur_block++;
nexpaq 1:55a6170b404f 303 }
nexpaq 1:55a6170b404f 304
nexpaq 1:55a6170b404f 305 if (end != heap_main_end) {
nexpaq 1:55a6170b404f 306 end++;
nexpaq 1:55a6170b404f 307 if (*end < 0) {
nexpaq 1:55a6170b404f 308 merged_data_size += (2 - *end);
nexpaq 1:55a6170b404f 309 if (-*end >= HOLE_T_SIZE) {
nexpaq 1:55a6170b404f 310 existing_end = hole_from_block_start(end);
nexpaq 1:55a6170b404f 311 }
nexpaq 1:55a6170b404f 312 end += (1 - *end);
nexpaq 1:55a6170b404f 313 }else{
nexpaq 1:55a6170b404f 314 end--;
nexpaq 1:55a6170b404f 315 }
nexpaq 1:55a6170b404f 316 }
nexpaq 1:55a6170b404f 317
nexpaq 1:55a6170b404f 318 hole_t *to_add = hole_from_block_start(start);
nexpaq 1:55a6170b404f 319 hole_t *before = NULL;
nexpaq 1:55a6170b404f 320 if (existing_end) {
nexpaq 1:55a6170b404f 321 // Extending hole described by "existing_end" downwards.
nexpaq 1:55a6170b404f 322 // Will replace with descriptor at bottom of merged block.
nexpaq 1:55a6170b404f 323 // (Can't use ns_list_replace, because of danger of overlap)
nexpaq 1:55a6170b404f 324 // Optimisation - note our position for insertion below.
nexpaq 1:55a6170b404f 325 before = ns_list_get_next(&holes_list, existing_end);
nexpaq 1:55a6170b404f 326 ns_list_remove(&holes_list, existing_end);
nexpaq 1:55a6170b404f 327 }
nexpaq 1:55a6170b404f 328 if (existing_start) {
nexpaq 1:55a6170b404f 329 // Extending hole described by "existing_start" upwards.
nexpaq 1:55a6170b404f 330 // No need to modify that descriptor - it remains at the bottom
nexpaq 1:55a6170b404f 331 // of the merged block to describe it.
nexpaq 1:55a6170b404f 332 } else {
nexpaq 1:55a6170b404f 333 // Didn't find adjacent descriptors, but may still
nexpaq 1:55a6170b404f 334 // be merging with small blocks without descriptors.
nexpaq 1:55a6170b404f 335 if ( merged_data_size >= HOLE_T_SIZE ) {
nexpaq 1:55a6170b404f 336 // Locate hole position in list, if we don't already know
nexpaq 1:55a6170b404f 337 // from merging with the block above.
nexpaq 1:55a6170b404f 338 if (!existing_end) {
nexpaq 1:55a6170b404f 339 ns_list_foreach(hole_t, ptr, &holes_list) {
nexpaq 1:55a6170b404f 340 if (ptr > to_add) {
nexpaq 1:55a6170b404f 341 before = ptr;
nexpaq 1:55a6170b404f 342 break;
nexpaq 1:55a6170b404f 343 }
nexpaq 1:55a6170b404f 344 }
nexpaq 1:55a6170b404f 345 }
nexpaq 1:55a6170b404f 346 if (before) {
nexpaq 1:55a6170b404f 347 ns_list_add_before(&holes_list, before, to_add);
nexpaq 1:55a6170b404f 348 } else {
nexpaq 1:55a6170b404f 349 ns_list_add_to_end(&holes_list, to_add);
nexpaq 1:55a6170b404f 350 }
nexpaq 1:55a6170b404f 351
nexpaq 1:55a6170b404f 352 }
nexpaq 1:55a6170b404f 353 }
nexpaq 1:55a6170b404f 354 *start = -merged_data_size;
nexpaq 1:55a6170b404f 355 *end = -merged_data_size;
nexpaq 1:55a6170b404f 356 }
nexpaq 1:55a6170b404f 357 #endif
nexpaq 1:55a6170b404f 358
nexpaq 1:55a6170b404f 359 void ns_dyn_mem_free(void *block)
nexpaq 1:55a6170b404f 360 {
nexpaq 1:55a6170b404f 361 #ifndef STANDARD_MALLOC
nexpaq 1:55a6170b404f 362 int *ptr = block;
nexpaq 1:55a6170b404f 363 int size;
nexpaq 1:55a6170b404f 364
nexpaq 1:55a6170b404f 365 if (!block) {
nexpaq 1:55a6170b404f 366 return;
nexpaq 1:55a6170b404f 367 }
nexpaq 1:55a6170b404f 368
nexpaq 1:55a6170b404f 369 if (!heap_main) {
nexpaq 1:55a6170b404f 370 heap_failure(NS_DYN_MEM_HEAP_SECTOR_UNITIALIZED);
nexpaq 1:55a6170b404f 371 return;
nexpaq 1:55a6170b404f 372 }
nexpaq 1:55a6170b404f 373
nexpaq 1:55a6170b404f 374 platform_enter_critical();
nexpaq 1:55a6170b404f 375 ptr --;
nexpaq 1:55a6170b404f 376 //Read Current Size
nexpaq 1:55a6170b404f 377 size = *ptr;
nexpaq 1:55a6170b404f 378 if (size < 0) {
nexpaq 1:55a6170b404f 379 heap_failure(NS_DYN_MEM_DOUBLE_FREE);
nexpaq 1:55a6170b404f 380 } else if (ptr < heap_main || ptr >= heap_main_end) {
nexpaq 1:55a6170b404f 381 heap_failure(NS_DYN_MEM_POINTER_NOT_VALID);
nexpaq 1:55a6170b404f 382 } else if ((ptr + size) >= heap_main_end) {
nexpaq 1:55a6170b404f 383 heap_failure(NS_DYN_MEM_POINTER_NOT_VALID);
nexpaq 1:55a6170b404f 384 } else {
nexpaq 1:55a6170b404f 385 if (ns_block_validate(ptr, 1) != 0) {
nexpaq 1:55a6170b404f 386 heap_failure(NS_DYN_MEM_HEAP_SECTOR_CORRUPTED);
nexpaq 1:55a6170b404f 387 } else {
nexpaq 1:55a6170b404f 388 ns_free_and_merge_with_adjacent_blocks(ptr, size);
nexpaq 1:55a6170b404f 389 if (mem_stat_info_ptr) {
nexpaq 1:55a6170b404f 390 //Update Free Counter
nexpaq 1:55a6170b404f 391 dev_stat_update(DEV_HEAP_FREE, (size + 2) * sizeof(int));
nexpaq 1:55a6170b404f 392 }
nexpaq 1:55a6170b404f 393 }
nexpaq 1:55a6170b404f 394 }
nexpaq 1:55a6170b404f 395 platform_exit_critical();
nexpaq 1:55a6170b404f 396 #else
nexpaq 1:55a6170b404f 397 platform_enter_critical();
nexpaq 1:55a6170b404f 398 free(block);
nexpaq 1:55a6170b404f 399 platform_exit_critical();
nexpaq 1:55a6170b404f 400 #endif
nexpaq 1:55a6170b404f 401 }