Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
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 Sun Jul 17 2022 08:25:22 by 1.7.2