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.
dynmemtest.cpp
00001 /* 00002 * Copyright (c) 2015 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 "error_callback.h" 00021 00022 TEST_GROUP(dynmem) 00023 { 00024 void setup() { 00025 reset_heap_error(); 00026 } 00027 00028 void teardown() { 00029 } 00030 }; 00031 00032 TEST(dynmem, init) 00033 { 00034 uint16_t size = 1000; 00035 uint8_t *heap = (uint8_t*)malloc(size); 00036 CHECK(NULL != heap); 00037 mem_stat_t info; 00038 reset_heap_error(); 00039 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00040 CHECK(info.heap_sector_size >= (size-64)); 00041 CHECK(!heap_have_failed()); 00042 CHECK(ns_dyn_mem_get_mem_stat() == &info); 00043 free(heap); 00044 } 00045 00046 TEST(dynmem, different_sizes) 00047 { 00048 reset_heap_error(); 00049 for (uint16_t size = 1000; size<32768; size++) { 00050 mem_stat_t info; 00051 uint8_t *heap = (uint8_t*)malloc(size); 00052 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00053 CHECK(info.heap_sector_size >= (size-64)); 00054 CHECK(!heap_have_failed()); 00055 CHECK(ns_dyn_mem_alloc(10)); 00056 free(heap); 00057 } 00058 } 00059 00060 TEST(dynmem, diff_alignment) 00061 { 00062 uint16_t size = 1000; 00063 mem_stat_t info; 00064 uint8_t *heap = (uint8_t*)malloc(size); 00065 uint8_t *ptr = heap; 00066 CHECK(NULL != heap); 00067 reset_heap_error(); 00068 for (int i=0; i<16; i++) { 00069 ptr++; size--; 00070 ns_dyn_mem_init(ptr, size, &heap_fail_callback, &info); 00071 CHECK(info.heap_sector_size >= (size-64)); 00072 CHECK(!heap_have_failed()); 00073 } 00074 free(heap); 00075 } 00076 00077 TEST(dynmem, ns_dyn_mem_alloc) 00078 { 00079 uint16_t size = 1000; 00080 mem_stat_t info; 00081 void *p[size]; 00082 uint8_t *heap = (uint8_t*)malloc(size); 00083 CHECK(NULL != heap); 00084 reset_heap_error(); 00085 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00086 CHECK(!heap_have_failed()); 00087 int block = 1; 00088 00089 int i; 00090 for (i=0; i<size; i++) { 00091 p[i] = ns_dyn_mem_alloc(block); 00092 if (!p[i]) 00093 break; 00094 } 00095 CHECK(!heap_have_failed()); 00096 CHECK(info.heap_alloc_fail_cnt == 1); 00097 CHECK(info.heap_sector_alloc_cnt == i); 00098 CHECK(info.heap_sector_allocated_bytes == info.heap_sector_allocated_bytes_max); 00099 00100 for (; i>=0; i--) { 00101 ns_dyn_mem_free(p[i]); 00102 } 00103 CHECK(!heap_have_failed()); 00104 CHECK(info.heap_sector_alloc_cnt == 0); 00105 free(heap); 00106 } 00107 00108 TEST(dynmem, ns_dyn_mem_temporary_alloc) 00109 { 00110 uint16_t size = 1000; 00111 mem_stat_t info; 00112 void *p[size]; 00113 uint8_t *heap = (uint8_t*)malloc(size); 00114 CHECK(NULL != heap); 00115 reset_heap_error(); 00116 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00117 CHECK(!heap_have_failed()); 00118 int block = 1; 00119 00120 int i; 00121 for (i=0; i<size; i++) { 00122 p[i] = ns_dyn_mem_temporary_alloc(block); 00123 if (!p[i]) 00124 break; 00125 } 00126 CHECK(!heap_have_failed()); 00127 CHECK(info.heap_alloc_fail_cnt == 1); 00128 CHECK(info.heap_sector_alloc_cnt == i); 00129 CHECK(info.heap_sector_allocated_bytes == info.heap_sector_allocated_bytes_max); 00130 00131 for (; i>=0; i--) { 00132 ns_dyn_mem_free(p[i]); 00133 } 00134 CHECK(!heap_have_failed()); 00135 CHECK(info.heap_sector_alloc_cnt == 0); 00136 free(heap); 00137 } 00138 00139 TEST(dynmem, test_both_allocs_with_hole_usage) { 00140 uint16_t size = 112; 00141 mem_stat_t info; 00142 void *p[size]; 00143 uint8_t *heap = (uint8_t*)malloc(size); 00144 CHECK(NULL != heap); 00145 reset_heap_error(); 00146 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00147 CHECK(!heap_have_failed()); 00148 00149 void *ptr = ns_dyn_mem_alloc(15); 00150 void *ptr2 = ns_dyn_mem_alloc(4); 00151 00152 ns_dyn_mem_free(ptr); 00153 ns_dyn_mem_free(ptr2); 00154 CHECK(info.heap_sector_allocated_bytes == 0); 00155 00156 void *ptr3 = ns_dyn_mem_temporary_alloc(15); 00157 void *ptr4 = ns_dyn_mem_temporary_alloc(5); 00158 00159 ns_dyn_mem_free(ptr3); 00160 ns_dyn_mem_free(ptr4); 00161 00162 00163 CHECK(info.heap_sector_allocated_bytes == 0); 00164 00165 free(heap); 00166 } 00167 00168 TEST(dynmem, test_temp_alloc_with_skipping_hole) { 00169 uint16_t size = 1000; 00170 mem_stat_t info; 00171 void *p[size]; 00172 uint8_t *heap = (uint8_t*)malloc(size); 00173 CHECK(NULL != heap); 00174 reset_heap_error(); 00175 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00176 CHECK(!heap_have_failed()); 00177 00178 void *ptr1 = ns_dyn_mem_temporary_alloc(15); 00179 void *ptr2 = ns_dyn_mem_temporary_alloc(5); 00180 00181 ns_dyn_mem_free(ptr1); 00182 void *ptr3 = ns_dyn_mem_temporary_alloc(35); 00183 ns_dyn_mem_free(ptr2); 00184 ns_dyn_mem_free(ptr3); 00185 00186 00187 CHECK(info.heap_sector_allocated_bytes == 0); 00188 00189 free(heap); 00190 } 00191 00192 TEST(dynmem, zero_allocate) 00193 { 00194 uint16_t size = 1000; 00195 mem_stat_t info; 00196 uint8_t *heap = (uint8_t*)malloc(size); 00197 uint8_t *ptr = heap; 00198 CHECK(NULL != heap); 00199 reset_heap_error(); 00200 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00201 CHECK(!heap_have_failed()); 00202 ns_dyn_mem_alloc(0); 00203 CHECK(heap_have_failed()); 00204 CHECK(NS_DYN_MEM_ALLOCATE_SIZE_NOT_VALID == current_heap_error); 00205 free(heap); 00206 } 00207 00208 TEST(dynmem, too_big) 00209 { 00210 uint16_t size = 1000; 00211 mem_stat_t info; 00212 uint8_t *heap = (uint8_t*)malloc(size); 00213 uint8_t *ptr = heap; 00214 CHECK(NULL != heap); 00215 reset_heap_error(); 00216 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00217 CHECK(!heap_have_failed()); 00218 ns_dyn_mem_alloc(size); 00219 CHECK(heap_have_failed()); 00220 CHECK(NS_DYN_MEM_ALLOCATE_SIZE_NOT_VALID == current_heap_error); 00221 free(heap); 00222 } 00223 00224 TEST(dynmem, corrupted_memory) 00225 { 00226 uint16_t size = 1000; 00227 mem_stat_t info; 00228 uint8_t *heap = (uint8_t*)malloc(size); 00229 uint8_t *ptr = heap; 00230 CHECK(NULL != heap); 00231 reset_heap_error(); 00232 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00233 CHECK(!heap_have_failed()); 00234 int *pt = (int *)ns_dyn_mem_alloc(8); 00235 CHECK(!heap_have_failed()); 00236 pt -= 2; 00237 *pt = 0; 00238 ns_dyn_mem_alloc(8); 00239 CHECK(NS_DYN_MEM_HEAP_SECTOR_CORRUPTED == current_heap_error); 00240 free(heap); 00241 } 00242 00243 TEST(dynmem, no_big_enough_sector) { 00244 uint16_t size = 112; 00245 mem_stat_t info; 00246 uint8_t *heap = (uint8_t*)malloc(size); 00247 uint8_t *ptr = heap; 00248 CHECK(NULL != heap); 00249 reset_heap_error(); 00250 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00251 CHECK(!heap_have_failed()); 00252 int *pt = (int *)ns_dyn_mem_alloc(8); 00253 pt = (int *)ns_dyn_mem_alloc(8); 00254 ns_dyn_mem_alloc(8); 00255 ns_dyn_mem_temporary_alloc(8); 00256 ns_dyn_mem_temporary_alloc(8); 00257 00258 ns_dyn_mem_free(pt); 00259 00260 pt = (int *)ns_dyn_mem_temporary_alloc(32); 00261 CHECK(NULL == pt); 00262 free(heap); 00263 } 00264 00265 TEST(dynmem, diff_sizes) 00266 { 00267 uint16_t size = 1000; 00268 mem_stat_t info; 00269 void *p; 00270 uint8_t *heap = (uint8_t*)malloc(size); 00271 CHECK(NULL != heap); 00272 reset_heap_error(); 00273 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00274 CHECK(!heap_have_failed()); 00275 int i; 00276 for (i=1; i<(size-64); i++) { 00277 p = ns_dyn_mem_temporary_alloc(i); 00278 CHECK(p); 00279 ns_dyn_mem_free(p); 00280 CHECK(!heap_have_failed()); 00281 } 00282 CHECK(!heap_have_failed()); 00283 CHECK(info.heap_sector_alloc_cnt == 0); 00284 free(heap); 00285 } 00286 00287 TEST(dynmem, double_free) 00288 { 00289 uint16_t size = 1000; 00290 mem_stat_t info; 00291 uint8_t *heap = (uint8_t*)malloc(size); 00292 void *p; 00293 CHECK(NULL != heap); 00294 reset_heap_error(); 00295 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00296 CHECK(!heap_have_failed()); 00297 p = ns_dyn_mem_alloc(100); 00298 CHECK(p); 00299 ns_dyn_mem_free(p); 00300 CHECK(!heap_have_failed()); 00301 ns_dyn_mem_free(p); 00302 CHECK(heap_have_failed()); 00303 CHECK(NS_DYN_MEM_DOUBLE_FREE == current_heap_error); 00304 free(heap); 00305 } 00306 00307 TEST(dynmem, middle_free) 00308 { 00309 uint16_t size = 1000; 00310 mem_stat_t info; 00311 uint8_t *heap = (uint8_t*)malloc(size); 00312 void *p[3]; 00313 CHECK(NULL != heap); 00314 reset_heap_error(); 00315 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00316 CHECK(!heap_have_failed()); 00317 for (int i=0; i<3; i++) { 00318 p[i] = ns_dyn_mem_temporary_alloc(100); 00319 CHECK(p); 00320 } 00321 ns_dyn_mem_free(p[1]); 00322 CHECK(!heap_have_failed()); 00323 ns_dyn_mem_free(p[0]); 00324 CHECK(!heap_have_failed()); 00325 ns_dyn_mem_free(p[2]); 00326 CHECK(!heap_have_failed()); 00327 free(heap); 00328 } 00329 00330 TEST(dynmem, over_by_one) 00331 { 00332 uint16_t size = 1000; 00333 mem_stat_t info; 00334 uint8_t *heap = (uint8_t*)malloc(size); 00335 uint8_t *p; 00336 CHECK(NULL != heap); 00337 reset_heap_error(); 00338 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00339 CHECK(!heap_have_failed()); 00340 p = (uint8_t *)ns_dyn_mem_alloc(100); 00341 CHECK(p); 00342 p[100] = 0xff; 00343 ns_dyn_mem_free(p); 00344 CHECK(heap_have_failed()); 00345 CHECK(NS_DYN_MEM_HEAP_SECTOR_CORRUPTED == current_heap_error); 00346 free(heap); 00347 } 00348 00349 TEST(dynmem, not_from_this_heap) 00350 { 00351 uint16_t size = 1000; 00352 mem_stat_t info; 00353 uint8_t *heap = (uint8_t*)malloc(size); 00354 uint8_t *p; 00355 CHECK(NULL != heap); 00356 reset_heap_error(); 00357 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00358 CHECK(!heap_have_failed()); 00359 p = (uint8_t *)ns_dyn_mem_alloc(100); 00360 CHECK(p); 00361 ns_dyn_mem_free(&heap[-1]); 00362 CHECK(heap_have_failed()); 00363 CHECK(NS_DYN_MEM_POINTER_NOT_VALID == current_heap_error); 00364 reset_heap_error(); 00365 ns_dyn_mem_free(&heap[1001]); 00366 CHECK(heap_have_failed()); 00367 CHECK(NS_DYN_MEM_POINTER_NOT_VALID == current_heap_error); 00368 free(heap); 00369 } 00370 00371 TEST(dynmem, free_on_empty_heap) 00372 { 00373 uint16_t size = 1000; 00374 mem_stat_t info; 00375 uint8_t *heap = (uint8_t*)malloc(size); 00376 uint8_t *p; 00377 CHECK(NULL != heap); 00378 reset_heap_error(); 00379 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00380 CHECK(!heap_have_failed()); 00381 ns_dyn_mem_free(&heap[1]); 00382 CHECK(heap_have_failed()); 00383 CHECK(NS_DYN_MEM_POINTER_NOT_VALID == current_heap_error); 00384 free(heap); 00385 } 00386 00387 TEST(dynmem, not_negative_stats) 00388 { 00389 uint16_t size = 1000; 00390 mem_stat_t info; 00391 uint8_t *heap = (uint8_t*)malloc(size); 00392 void *p; 00393 CHECK(NULL != heap); 00394 reset_heap_error(); 00395 ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); 00396 CHECK(!heap_have_failed()); 00397 CHECK(info.heap_sector_allocated_bytes == 0); 00398 ns_dyn_mem_alloc(8); 00399 p = ns_dyn_mem_alloc(8); 00400 ns_dyn_mem_alloc(8); 00401 CHECK(info.heap_sector_allocated_bytes >= 24); 00402 int16_t last_value = info.heap_sector_allocated_bytes; 00403 ns_dyn_mem_free(p); 00404 CHECK(info.heap_sector_allocated_bytes >= 16); 00405 CHECK(info.heap_sector_allocated_bytes < last_value); 00406 last_value = info.heap_sector_allocated_bytes; 00407 for (int i=0; i<10; i++) { 00408 p = ns_dyn_mem_alloc(1); 00409 ns_dyn_mem_free(p); 00410 } 00411 CHECK(info.heap_sector_allocated_bytes == last_value); 00412 free(heap); 00413 } 00414 00415 TEST(dynmem, test_invalid_pointer_freed) { 00416 uint16_t size = 92; 00417 uint8_t *heap = (uint8_t*)malloc(size); 00418 CHECK(NULL != heap); 00419 reset_heap_error(); 00420 ns_dyn_mem_init(heap, size, &heap_fail_callback, NULL); 00421 int *ptr = (int *)ns_dyn_mem_alloc(4); 00422 ptr--; 00423 *ptr = 16; 00424 ptr++; 00425 ns_dyn_mem_free(ptr); 00426 CHECK(NS_DYN_MEM_POINTER_NOT_VALID == current_heap_error); 00427 00428 free(heap); 00429 } 00430 00431 TEST(dynmem, test_merge_corrupted_previous_block) { 00432 uint16_t size = 1000; 00433 uint8_t *heap = (uint8_t*)malloc(size); 00434 uint8_t *p; 00435 CHECK(NULL != heap); 00436 reset_heap_error(); 00437 ns_dyn_mem_init(heap, size, &heap_fail_callback, NULL); 00438 CHECK(!heap_have_failed()); 00439 00440 int *ptr = (int *)ns_dyn_mem_alloc(4); 00441 int *ptr2 = (int *)ns_dyn_mem_alloc(4); 00442 ns_dyn_mem_free(ptr); 00443 ptr = ptr2 - 2; 00444 *ptr = -2; 00445 ns_dyn_mem_free(ptr2); 00446 00447 CHECK(NS_DYN_MEM_HEAP_SECTOR_CORRUPTED == current_heap_error); 00448 00449 free(heap); 00450 } 00451 00452 TEST(dynmem, test_free_corrupted_next_block) { 00453 uint16_t size = 1000; 00454 uint8_t *heap = (uint8_t*)malloc(size); 00455 uint8_t *p; 00456 CHECK(NULL != heap); 00457 reset_heap_error(); 00458 ns_dyn_mem_init(heap, size, &heap_fail_callback, NULL); 00459 CHECK(!heap_have_failed()); 00460 00461 int *ptr = (int *)ns_dyn_mem_temporary_alloc(4); 00462 int *ptr2 = (int *)ns_dyn_mem_temporary_alloc(4); 00463 ns_dyn_mem_free(ptr); 00464 ptr = ptr2 + 2; 00465 *ptr = -2; 00466 ns_dyn_mem_free(ptr2); 00467 00468 CHECK(NS_DYN_MEM_HEAP_SECTOR_CORRUPTED == current_heap_error); 00469 00470 free(heap); 00471 } 00472 00473 //NOTE! This test must be last! 00474 TEST(dynmem, uninitialized_test){ 00475 void *p = ns_dyn_mem_alloc(4); 00476 ns_dyn_mem_free(p); 00477 CHECK(p == NULL); 00478 }
Generated on Tue Jul 12 2022 14:23:33 by
