Rtos API example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers dynmemtest.cpp Source File

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 }