Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
dynmemtest.cpp
00001 /* 00002 * Copyright (c) 2015-2018 ARM Limited. All rights reserved. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * Licensed under the Apache License, Version 2.0 (the License); you may 00005 * not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an AS IS BASIS, WITHOUT 00012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #include "CppUTest/TestHarness.h" 00017 #include "nsdynmemLIB.h" 00018 #include <stdlib.h> 00019 #include <stdio.h> 00020 #include <string.h> 00021 #include "error_callback.h" 00022 00023 // hardcoded amount of regions, keep in sync with nsdynmemlib "REGION_COUNT" 00024 #define NS_MEM_REGION_CNT (3) 00025 // size of nsdynmemlib book keeping data ns_mem_book_t 00026 #define NS_MEM_BOOK_SIZE (64 + (NS_MEM_REGION_CNT-1)*2*sizeof(ns_mem_heap_size_t)) 00027 #define NS_MEM_BOOK_SIZE_WITH_HOLE (NS_MEM_BOOK_SIZE + 2*sizeof(ns_mem_heap_size_t)) 00028 00029 int ret_val; 00030 00031 TEST_GROUP(dynmem) 00032 { 00033 void setup() { 00034 reset_heap_error(); 00035 } 00036 00037 void teardown() { 00038 } 00039 }; 00040 00041 TEST(dynmem, init) 00042 { 00043 uint16_t size = 1000; 00044 uint8_t *heap = (uint8_t *)malloc(size); 00045 CHECK(NULL != heap); 00046 mem_stat_t info; 00047 reset_heap_error(); 00048 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00049 CHECK(info.heap_sector_size == (size - NS_MEM_BOOK_SIZE)); 00050 CHECK(!heap_have_failed()); 00051 CHECK(ns_dyn_mem_get_mem_stat() == &info); 00052 free(heap); 00053 } 00054 00055 TEST(dynmem, different_sizes) 00056 { 00057 reset_heap_error(); 00058 for (uint16_t size = 1000; size < 32768; size++) { 00059 mem_stat_t info; 00060 uint8_t *heap = (uint8_t *)malloc(size); 00061 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00062 CHECK(info.heap_sector_size >= (size - NS_MEM_BOOK_SIZE_WITH_HOLE)); 00063 CHECK(!heap_have_failed()); 00064 CHECK(ns_dyn_mem_alloc(10)); 00065 free(heap); 00066 } 00067 } 00068 00069 TEST(dynmem, diff_alignment) 00070 { 00071 uint16_t size = 1000; 00072 mem_stat_t info; 00073 uint8_t *heap = (uint8_t *)malloc(size); 00074 uint8_t *ptr = heap; 00075 CHECK(NULL != heap); 00076 reset_heap_error(); 00077 for (int i = 0; i < 16; i++) { 00078 ptr++; 00079 size--; 00080 ns_dyn_mem_init(ptr, size, &heap_fail_callback, &info); 00081 CHECK(info.heap_sector_size >= (size - NS_MEM_BOOK_SIZE_WITH_HOLE)); 00082 CHECK(!heap_have_failed()); 00083 } 00084 free(heap); 00085 } 00086 00087 TEST(dynmem, heap_add_region_api) 00088 { 00089 #if (NS_MEM_REGION_CNT > 1) 00090 uint16_t size = 1000; 00091 uint8_t *heap = (uint8_t *)malloc(size); 00092 uint8_t *heap2add = (uint8_t *)malloc(size); 00093 uint8_t *heap2add2 = (uint8_t *)malloc(size); 00094 00095 mem_stat_t info; 00096 00097 reset_heap_error(); 00098 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00099 CHECK(info.heap_sector_size == (size - NS_MEM_BOOK_SIZE)) 00100 00101 // param error, return <0 00102 ret_val = ns_dyn_mem_region_add(NULL, size); 00103 CHECK(0 != ret_val); 00104 00105 // param error, return <0 00106 ret_val = ns_dyn_mem_region_add(heap2add, 0); 00107 CHECK(0 != ret_val); 00108 00109 // param error, return <0 00110 ret_val = ns_dyn_mem_region_add(heap2add, 8); 00111 CHECK(0 != ret_val); 00112 00113 // All OK - success, 1 reserved for bookkeeping 00114 ret_val = ns_dyn_mem_region_add(heap2add, size); 00115 CHECK(0 == ret_val); 00116 00117 CHECK(!heap_have_failed()); 00118 CHECK(ns_dyn_mem_get_mem_stat() == &info); 00119 CHECK(info.heap_sector_size == (2 * size - NS_MEM_BOOK_SIZE)) 00120 00121 // All OK - add more memory again success 00122 ret_val = ns_dyn_mem_region_add(heap2add2, size); 00123 CHECK(0 == ret_val); 00124 CHECK(info.heap_sector_size == (3 * size - NS_MEM_BOOK_SIZE)) 00125 00126 free(heap); 00127 free(heap2add); 00128 free(heap2add2); 00129 #endif 00130 } 00131 00132 TEST(dynmem, heap_add_region) 00133 { 00134 #if (NS_MEM_REGION_CNT > 1 && NS_MEM_REGION_CNT < 4) 00135 uint16_t size = 200; 00136 uint8_t *heap = (uint8_t *)malloc(size); 00137 uint8_t *heap_add1 = (uint8_t *)malloc(size); 00138 uint8_t *heap_add2 = (uint8_t *)malloc(size); 00139 uint8_t *heap_add3 = (uint8_t *)malloc(size); 00140 void *p[size * 4]; 00141 00142 mem_stat_t info; 00143 00144 reset_heap_error(); 00145 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00146 CHECK(info.heap_sector_size == (size - NS_MEM_BOOK_SIZE)) 00147 00148 ret_val = ns_dyn_mem_region_add(heap_add1, size); 00149 CHECK(0 == ret_val); 00150 00151 // region already added, therefore fails 00152 ret_val = ns_dyn_mem_region_add(heap_add1, size); 00153 CHECK(0 != ret_val); 00154 00155 ret_val = ns_dyn_mem_region_add(heap_add3, size); 00156 CHECK(0 == ret_val); 00157 00158 // There is room for 2 additional regions , therfore fails 00159 ret_val = ns_dyn_mem_region_add(heap_add2, size); 00160 CHECK(0 != ret_val); 00161 00162 CHECK(info.heap_sector_size == (3 * size - NS_MEM_BOOK_SIZE)) 00163 00164 CHECK(!heap_have_failed()); 00165 int block_size = 10; 00166 00167 int i; 00168 for (i = 0; i < size * 3; i++) { 00169 p[i] = ns_dyn_mem_alloc(block_size); 00170 if (p[i]) { 00171 memset(p[i], 0xb0, block_size); 00172 } else { 00173 break; 00174 } 00175 } 00176 CHECK(!heap_have_failed()); 00177 CHECK(info.heap_alloc_fail_cnt == 1); 00178 CHECK(info.heap_sector_alloc_cnt == i); 00179 CHECK(info.heap_sector_allocated_bytes == info.heap_sector_allocated_bytes_max); 00180 00181 for (; i >= 0; i--) { 00182 ns_dyn_mem_free(p[i]); 00183 } 00184 CHECK(!heap_have_failed()); 00185 CHECK(info.heap_sector_alloc_cnt == 0); 00186 00187 free(heap); 00188 free(heap_add1); 00189 free(heap_add2); 00190 free(heap_add3); 00191 #endif 00192 } 00193 00194 TEST(dynmem, heap_add_region_randomized) 00195 { 00196 /** 00197 * Test: 00198 * - multiple regions 00199 * - regions are not from continous 00200 * - all memory allocated from heap 00201 * - blocks are deallocated in random order 00202 */ 00203 #if (NS_MEM_REGION_CNT > 1) 00204 uint32_t size = 200000; 00205 uint8_t *heap_ptr[NS_MEM_REGION_CNT]; // heap memory regions 00206 void *ptrs[size * NS_MEM_REGION_CNT / 4] = {0}; // allocated memory pointers 00207 mem_stat_t info; 00208 uint8_t *gap_between_regions = NULL; 00209 00210 for (int cnt = 0; cnt < NS_MEM_REGION_CNT; cnt++) { 00211 heap_ptr[cnt] = (uint8_t *)malloc(size); 00212 if (gap_between_regions) { 00213 free(gap_between_regions); 00214 } 00215 gap_between_regions = (uint8_t *)malloc(size / 3); 00216 } 00217 free(gap_between_regions); 00218 00219 reset_heap_error(); 00220 ns_dyn_mem_init(heap_ptr[0], size, &heap_fail_callback, &info); 00221 CHECK(info.heap_sector_size == (size - NS_MEM_BOOK_SIZE)) 00222 00223 for (int cnt = NS_MEM_REGION_CNT - 1; cnt > 0; cnt--) { 00224 ret_val = ns_dyn_mem_region_add(heap_ptr[cnt], size); 00225 CHECK(0 == ret_val); 00226 } 00227 00228 CHECK(info.heap_sector_size == (NS_MEM_REGION_CNT * size - NS_MEM_BOOK_SIZE)) 00229 00230 CHECK(!heap_have_failed()); 00231 00232 srand(time(NULL)); 00233 int block_size; 00234 int i; 00235 for (i = 0; i < size * NS_MEM_REGION_CNT; i++) { 00236 // allocate huge amount of small blocks until allocation fails 00237 block_size = (rand() % 4) + 1; 00238 ptrs[i] = ns_dyn_mem_alloc(block_size); 00239 if (ptrs[i]) { 00240 memset(ptrs[i], 0xb0, block_size); 00241 } else { 00242 break; 00243 } 00244 } 00245 CHECK(!heap_have_failed()); 00246 CHECK(info.heap_alloc_fail_cnt == 1); 00247 CHECK(info.heap_sector_alloc_cnt == i); 00248 CHECK(info.heap_sector_allocated_bytes == info.heap_sector_allocated_bytes_max); 00249 00250 // free allocated memmory blocks in random order 00251 int block_id; 00252 do { 00253 block_id = (rand() % i); 00254 if (ptrs[block_id] != NULL) { 00255 ns_dyn_mem_free(ptrs[block_id]); 00256 ptrs[block_id] = NULL; 00257 } 00258 } while (info.heap_sector_alloc_cnt != 0); 00259 00260 00261 CHECK(!heap_have_failed()); 00262 CHECK(info.heap_sector_alloc_cnt == 0); 00263 CHECK(info.heap_sector_allocated_bytes == 0); 00264 00265 for (int cnt = 0; cnt < NS_MEM_REGION_CNT; cnt++) { 00266 free(heap_ptr[cnt]); 00267 } 00268 #endif 00269 } 00270 00271 TEST(dynmem, ns_dyn_mem_alloc) 00272 { 00273 uint16_t size = 1000; 00274 mem_stat_t info; 00275 void *p[size]; 00276 uint8_t *heap = (uint8_t *)malloc(size); 00277 CHECK(NULL != heap); 00278 reset_heap_error(); 00279 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00280 CHECK(!heap_have_failed()); 00281 int block = 1; 00282 00283 int i; 00284 for (i = 0; i < size; i++) { 00285 p[i] = ns_dyn_mem_alloc(block); 00286 00287 if (p[i]) { 00288 memset(p[i], 0xb0, block); 00289 } else { 00290 break; 00291 } 00292 } 00293 CHECK(!heap_have_failed()); 00294 CHECK(info.heap_alloc_fail_cnt == 1); 00295 CHECK(info.heap_sector_alloc_cnt == i); 00296 CHECK(info.heap_sector_allocated_bytes == info.heap_sector_allocated_bytes_max); 00297 00298 for (; i >= 0; i--) { 00299 ns_dyn_mem_free(p[i]); 00300 } 00301 CHECK(!heap_have_failed()); 00302 CHECK(info.heap_sector_alloc_cnt == 0); 00303 free(heap); 00304 } 00305 00306 TEST(dynmem, ns_dyn_mem_temporary_alloc) 00307 { 00308 uint16_t size = 1000; 00309 mem_stat_t info; 00310 void *p[size]; 00311 uint8_t *heap = (uint8_t *)malloc(size); 00312 CHECK(NULL != heap); 00313 reset_heap_error(); 00314 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00315 CHECK(!heap_have_failed()); 00316 int block = 1; 00317 00318 int i; 00319 for (i = 0; i < size; i++) { 00320 p[i] = ns_dyn_mem_temporary_alloc(block); 00321 if (!p[i]) { 00322 break; 00323 } 00324 } 00325 CHECK(!heap_have_failed()); 00326 CHECK(info.heap_alloc_fail_cnt == 1); 00327 CHECK(info.heap_sector_alloc_cnt == i); 00328 CHECK(info.heap_sector_allocated_bytes == info.heap_sector_allocated_bytes_max); 00329 00330 for (; i >= 0; i--) { 00331 ns_dyn_mem_free(p[i]); 00332 } 00333 CHECK(!heap_have_failed()); 00334 CHECK(info.heap_sector_alloc_cnt == 0); 00335 free(heap); 00336 } 00337 00338 TEST(dynmem, ns_dyn_mem_temporary_alloc_with_heap_threshold) 00339 { 00340 uint16_t size = 1000; 00341 mem_stat_t info; 00342 void *p1, *p2; 00343 int ret_val; 00344 uint8_t *heap = (uint8_t *)malloc(size); 00345 CHECK(NULL != heap); 00346 reset_heap_error(); 00347 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00348 CHECK(!heap_have_failed()); 00349 00350 // test1: temporary alloc will fail if there is less than 5% heap free 00351 p1 = ns_dyn_mem_temporary_alloc((size - NS_MEM_BOOK_SIZE_WITH_HOLE) * 0.96); 00352 CHECK(!heap_have_failed()); 00353 CHECK(p1); 00354 p2 = ns_dyn_mem_temporary_alloc((size - NS_MEM_BOOK_SIZE_WITH_HOLE) * 0.02); 00355 CHECK(p2 == NULL); 00356 CHECK(!heap_have_failed()); 00357 CHECK(info.heap_alloc_fail_cnt == 1); 00358 00359 // Test2, disable threshold feature and try p2 allocation again 00360 ns_dyn_mem_set_temporary_alloc_free_heap_threshold(0, 0); 00361 p2 = ns_dyn_mem_temporary_alloc((size - NS_MEM_BOOK_SIZE_WITH_HOLE) * 0.02); 00362 CHECK(!heap_have_failed()); 00363 CHECK(p2); 00364 ns_dyn_mem_free(p1); 00365 ns_dyn_mem_free(p2); 00366 CHECK(info.heap_alloc_fail_cnt == 1); 00367 CHECK(info.heap_sector_alloc_cnt == 0); 00368 00369 // Test3, enable feature by free heap percentage 00370 ns_dyn_mem_set_temporary_alloc_free_heap_threshold(40, 0); 00371 p1 = ns_dyn_mem_temporary_alloc((size - NS_MEM_BOOK_SIZE_WITH_HOLE) * 0.65); 00372 CHECK(p1); 00373 p2 = ns_dyn_mem_temporary_alloc((size - NS_MEM_BOOK_SIZE_WITH_HOLE) * 0.10); 00374 CHECK(p2 == NULL); 00375 ns_dyn_mem_free(p1); 00376 CHECK(!heap_have_failed()); 00377 CHECK(info.heap_alloc_fail_cnt == 2); 00378 CHECK(info.heap_sector_alloc_cnt == 0); 00379 00380 // Test4, enable feature by free heap amount 00381 ns_dyn_mem_set_temporary_alloc_free_heap_threshold(0, 200); 00382 p1 = ns_dyn_mem_temporary_alloc(size - NS_MEM_BOOK_SIZE_WITH_HOLE - 100); 00383 CHECK(p1); 00384 p2 = ns_dyn_mem_temporary_alloc(1); 00385 CHECK(p2 == NULL); 00386 ns_dyn_mem_free(p1); 00387 00388 // Test5, illegal API parameters 00389 ret_val = ns_dyn_mem_set_temporary_alloc_free_heap_threshold(0, size / 2); 00390 CHECK(ret_val == -2); 00391 ret_val = ns_dyn_mem_set_temporary_alloc_free_heap_threshold(0, size * 2); 00392 CHECK(ret_val == -2); 00393 ret_val = ns_dyn_mem_set_temporary_alloc_free_heap_threshold(51, 0); 00394 CHECK(ret_val == -2); 00395 ret_val = ns_dyn_mem_set_temporary_alloc_free_heap_threshold(255, 0); 00396 CHECK(ret_val == -2); 00397 00398 CHECK(!heap_have_failed()); 00399 CHECK(info.heap_alloc_fail_cnt == 3); 00400 CHECK(info.heap_sector_alloc_cnt == 0); 00401 free(heap); 00402 00403 // Test6, feature is disabled if info is not set 00404 heap = (uint8_t *)malloc(size); 00405 CHECK(NULL != heap); 00406 ns_dyn_mem_init(heap, size, &heap_fail_callback, NULL); 00407 ret_val = ns_dyn_mem_set_temporary_alloc_free_heap_threshold(0, 0); 00408 CHECK(ret_val == -1); 00409 CHECK(!heap_have_failed()); 00410 free(heap); 00411 } 00412 00413 TEST(dynmem, test_both_allocs_with_hole_usage) 00414 { 00415 uint16_t size = NS_MEM_BOOK_SIZE_WITH_HOLE + 15 + 5; 00416 mem_stat_t info; 00417 void *p[size]; 00418 uint8_t *heap = (uint8_t *)malloc(size); 00419 CHECK(NULL != heap); 00420 reset_heap_error(); 00421 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00422 CHECK(!heap_have_failed()); 00423 00424 void *ptr = ns_dyn_mem_alloc(15); 00425 void *ptr2 = ns_dyn_mem_alloc(4); 00426 00427 ns_dyn_mem_free(ptr); 00428 ns_dyn_mem_free(ptr2); 00429 CHECK(info.heap_sector_allocated_bytes == 0); 00430 00431 void *ptr3 = ns_dyn_mem_temporary_alloc(15); 00432 void *ptr4 = ns_dyn_mem_temporary_alloc(5); 00433 00434 ns_dyn_mem_free(ptr3); 00435 ns_dyn_mem_free(ptr4); 00436 00437 00438 CHECK(info.heap_sector_allocated_bytes == 0); 00439 00440 free(heap); 00441 } 00442 00443 TEST(dynmem, test_temp_alloc_with_skipping_hole) 00444 { 00445 uint16_t size = 1000; 00446 mem_stat_t info; 00447 void *p[size]; 00448 uint8_t *heap = (uint8_t *)malloc(size); 00449 CHECK(NULL != heap); 00450 reset_heap_error(); 00451 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00452 CHECK(!heap_have_failed()); 00453 00454 void *ptr1 = ns_dyn_mem_temporary_alloc(15); 00455 void *ptr2 = ns_dyn_mem_temporary_alloc(5); 00456 00457 ns_dyn_mem_free(ptr1); 00458 void *ptr3 = ns_dyn_mem_temporary_alloc(35); 00459 ns_dyn_mem_free(ptr2); 00460 ns_dyn_mem_free(ptr3); 00461 00462 00463 CHECK(info.heap_sector_allocated_bytes == 0); 00464 00465 free(heap); 00466 } 00467 00468 TEST(dynmem, zero_allocate) 00469 { 00470 uint16_t size = 1000; 00471 mem_stat_t info; 00472 uint8_t *heap = (uint8_t *)malloc(size); 00473 uint8_t *ptr = heap; 00474 CHECK(NULL != heap); 00475 reset_heap_error(); 00476 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00477 CHECK(!heap_have_failed()); 00478 ns_dyn_mem_alloc(0); 00479 CHECK(heap_have_failed()); 00480 CHECK(NS_DYN_MEM_ALLOCATE_SIZE_NOT_VALID == current_heap_error); 00481 free(heap); 00482 } 00483 00484 TEST(dynmem, too_big) 00485 { 00486 uint16_t size = 1000; 00487 mem_stat_t info; 00488 uint8_t *heap = (uint8_t *)malloc(size); 00489 uint8_t *ptr = heap; 00490 CHECK(NULL != heap); 00491 reset_heap_error(); 00492 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00493 CHECK(!heap_have_failed()); 00494 ns_dyn_mem_alloc(size); 00495 CHECK(heap_have_failed()); 00496 CHECK(NS_DYN_MEM_ALLOCATE_SIZE_NOT_VALID == current_heap_error); 00497 free(heap); 00498 } 00499 00500 TEST(dynmem, corrupted_memory) 00501 { 00502 uint16_t size = 1000; 00503 mem_stat_t info; 00504 uint8_t *heap = (uint8_t *)malloc(size); 00505 uint8_t *ptr = heap; 00506 CHECK(NULL != heap); 00507 reset_heap_error(); 00508 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00509 CHECK(!heap_have_failed()); 00510 int *pt = (int *)ns_dyn_mem_alloc(8); 00511 CHECK(!heap_have_failed()); 00512 pt -= 2; 00513 *pt = 0; 00514 ns_dyn_mem_alloc(8); 00515 CHECK(NS_DYN_MEM_HEAP_SECTOR_CORRUPTED == current_heap_error); 00516 free(heap); 00517 } 00518 00519 TEST(dynmem, no_big_enough_sector) 00520 { 00521 uint16_t size = NS_MEM_BOOK_SIZE_WITH_HOLE + (5 * 8); 00522 mem_stat_t info; 00523 uint8_t *heap = (uint8_t *)malloc(size); 00524 uint8_t *ptr = heap; 00525 CHECK(NULL != heap); 00526 reset_heap_error(); 00527 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00528 CHECK(!heap_have_failed()); 00529 int *pt = (int *)ns_dyn_mem_alloc(8); 00530 pt = (int *)ns_dyn_mem_alloc(8); 00531 ns_dyn_mem_alloc(8); 00532 ns_dyn_mem_temporary_alloc(8); 00533 ns_dyn_mem_temporary_alloc(8); 00534 00535 ns_dyn_mem_free(pt); 00536 00537 pt = (int *)ns_dyn_mem_temporary_alloc(32); 00538 CHECK(NULL == pt); 00539 free(heap); 00540 } 00541 00542 TEST(dynmem, diff_sizes) 00543 { 00544 uint16_t size = 1000; 00545 mem_stat_t info; 00546 void *p; 00547 uint8_t *heap = (uint8_t *)malloc(size); 00548 CHECK(NULL != heap); 00549 reset_heap_error(); 00550 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00551 CHECK(!heap_have_failed()); 00552 int i; 00553 for (i = 1; i < (size - NS_MEM_BOOK_SIZE_WITH_HOLE); i++) { 00554 p = ns_dyn_mem_temporary_alloc(i); 00555 CHECK(p); 00556 ns_dyn_mem_free(p); 00557 CHECK(!heap_have_failed()); 00558 } 00559 CHECK(!heap_have_failed()); 00560 CHECK(info.heap_sector_alloc_cnt == 0); 00561 free(heap); 00562 } 00563 00564 TEST(dynmem, double_free) 00565 { 00566 uint16_t size = 1000; 00567 mem_stat_t info; 00568 uint8_t *heap = (uint8_t *)malloc(size); 00569 void *p; 00570 CHECK(NULL != heap); 00571 reset_heap_error(); 00572 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00573 CHECK(!heap_have_failed()); 00574 p = ns_dyn_mem_alloc(100); 00575 CHECK(p); 00576 ns_dyn_mem_free(p); 00577 CHECK(!heap_have_failed()); 00578 ns_dyn_mem_free(p); 00579 CHECK(heap_have_failed()); 00580 CHECK(NS_DYN_MEM_DOUBLE_FREE == current_heap_error); 00581 free(heap); 00582 } 00583 00584 TEST(dynmem, middle_free) 00585 { 00586 uint16_t size = 1000; 00587 mem_stat_t info; 00588 uint8_t *heap = (uint8_t *)malloc(size); 00589 void *p[3]; 00590 CHECK(NULL != heap); 00591 reset_heap_error(); 00592 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00593 CHECK(!heap_have_failed()); 00594 for (int i = 0; i < 3; i++) { 00595 p[i] = ns_dyn_mem_temporary_alloc(100); 00596 CHECK(p); 00597 } 00598 ns_dyn_mem_free(p[1]); 00599 CHECK(!heap_have_failed()); 00600 ns_dyn_mem_free(p[0]); 00601 CHECK(!heap_have_failed()); 00602 ns_dyn_mem_free(p[2]); 00603 CHECK(!heap_have_failed()); 00604 free(heap); 00605 } 00606 00607 TEST(dynmem, over_by_one) 00608 { 00609 uint16_t size = 1000; 00610 mem_stat_t info; 00611 uint8_t *heap = (uint8_t *)malloc(size); 00612 uint8_t *p; 00613 CHECK(NULL != heap); 00614 reset_heap_error(); 00615 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00616 CHECK(!heap_have_failed()); 00617 p = (uint8_t *)ns_dyn_mem_alloc(100); 00618 CHECK(p); 00619 p[100] = 0xff; 00620 ns_dyn_mem_free(p); 00621 CHECK(heap_have_failed()); 00622 CHECK(NS_DYN_MEM_HEAP_SECTOR_CORRUPTED == current_heap_error); 00623 free(heap); 00624 } 00625 00626 TEST(dynmem, not_from_this_heap) 00627 { 00628 uint16_t size = 1000; 00629 mem_stat_t info; 00630 uint8_t *heap = (uint8_t *)malloc(size); 00631 uint8_t *p; 00632 CHECK(NULL != heap); 00633 reset_heap_error(); 00634 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00635 CHECK(!heap_have_failed()); 00636 p = (uint8_t *)ns_dyn_mem_alloc(100); 00637 CHECK(p); 00638 ns_dyn_mem_free(&heap[-1]); 00639 CHECK(heap_have_failed()); 00640 CHECK(NS_DYN_MEM_POINTER_NOT_VALID == current_heap_error); 00641 reset_heap_error(); 00642 ns_dyn_mem_free(&heap[1001]); 00643 CHECK(heap_have_failed()); 00644 CHECK(NS_DYN_MEM_POINTER_NOT_VALID == current_heap_error); 00645 free(heap); 00646 } 00647 00648 TEST(dynmem, free_on_empty_heap) 00649 { 00650 uint16_t size = 1000; 00651 mem_stat_t info; 00652 uint8_t *heap = (uint8_t *)malloc(size); 00653 uint8_t *p; 00654 CHECK(NULL != heap); 00655 reset_heap_error(); 00656 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00657 CHECK(!heap_have_failed()); 00658 ns_dyn_mem_free(&heap[1]); 00659 CHECK(heap_have_failed()); 00660 CHECK(NS_DYN_MEM_POINTER_NOT_VALID == current_heap_error); 00661 free(heap); 00662 } 00663 00664 TEST(dynmem, not_negative_stats) 00665 { 00666 uint16_t size = 1000; 00667 mem_stat_t info; 00668 uint8_t *heap = (uint8_t *)malloc(size); 00669 void *p; 00670 CHECK(NULL != heap); 00671 reset_heap_error(); 00672 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00673 CHECK(!heap_have_failed()); 00674 CHECK(info.heap_sector_allocated_bytes == 0); 00675 ns_dyn_mem_alloc(8); 00676 p = ns_dyn_mem_alloc(8); 00677 ns_dyn_mem_alloc(8); 00678 CHECK(info.heap_sector_allocated_bytes >= 24); 00679 int16_t last_value = info.heap_sector_allocated_bytes; 00680 ns_dyn_mem_free(p); 00681 CHECK(info.heap_sector_allocated_bytes >= 16); 00682 CHECK(info.heap_sector_allocated_bytes < last_value); 00683 last_value = info.heap_sector_allocated_bytes; 00684 for (int i = 0; i < 10; i++) { 00685 p = ns_dyn_mem_alloc(1); 00686 ns_dyn_mem_free(p); 00687 } 00688 CHECK(info.heap_sector_allocated_bytes == last_value); 00689 free(heap); 00690 } 00691 00692 TEST(dynmem, test_invalid_pointer_freed) 00693 { 00694 uint16_t size = 1000; 00695 uint8_t *heap = (uint8_t *)malloc(size); 00696 CHECK(NULL != heap); 00697 reset_heap_error(); 00698 ns_dyn_mem_init(heap, size, &heap_fail_callback, NULL); 00699 int *ptr = (int *)ns_dyn_mem_alloc(4); 00700 ptr--; 00701 *ptr = 16; 00702 ptr++; 00703 ns_dyn_mem_free(ptr); 00704 CHECK(NS_DYN_MEM_POINTER_NOT_VALID == current_heap_error); 00705 00706 free(heap); 00707 } 00708 00709 TEST(dynmem, test_merge_corrupted_previous_block) 00710 { 00711 uint16_t size = 1000; 00712 uint8_t *heap = (uint8_t *)malloc(size); 00713 uint8_t *p; 00714 CHECK(NULL != heap); 00715 reset_heap_error(); 00716 ns_dyn_mem_init(heap, size, &heap_fail_callback, NULL); 00717 CHECK(!heap_have_failed()); 00718 00719 int *ptr = (int *)ns_dyn_mem_alloc(4); 00720 int *ptr2 = (int *)ns_dyn_mem_alloc(4); 00721 ns_dyn_mem_free(ptr); 00722 ptr = ptr2 - 2; 00723 *ptr = -2; 00724 ns_dyn_mem_free(ptr2); 00725 00726 CHECK(NS_DYN_MEM_HEAP_SECTOR_CORRUPTED == current_heap_error); 00727 00728 free(heap); 00729 } 00730 00731 TEST(dynmem, test_free_corrupted_next_block) 00732 { 00733 uint16_t size = 1000; 00734 uint8_t *heap = (uint8_t *)malloc(size); 00735 uint8_t *p; 00736 CHECK(NULL != heap); 00737 reset_heap_error(); 00738 ns_dyn_mem_init(heap, size, &heap_fail_callback, NULL); 00739 CHECK(!heap_have_failed()); 00740 00741 int *ptr = (int *)ns_dyn_mem_temporary_alloc(4); 00742 int *ptr2 = (int *)ns_dyn_mem_temporary_alloc(4); 00743 ns_dyn_mem_free(ptr); 00744 ptr = ptr2 + 2; 00745 *ptr = -2; 00746 ns_dyn_mem_free(ptr2); 00747 00748 CHECK(NS_DYN_MEM_HEAP_SECTOR_CORRUPTED == current_heap_error); 00749 00750 free(heap); 00751 } 00752 00753 //NOTE! This test must be last! 00754 TEST(dynmem, uninitialized_test) 00755 { 00756 void *p = ns_dyn_mem_alloc(4); 00757 ns_dyn_mem_free(p); 00758 CHECK(p == NULL); 00759 }
Generated on Tue Jul 12 2022 13:54:17 by
