2022-09-19 05:46:55 -04:00
|
|
|
/*
|
|
|
|
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
|
|
|
*/
|
2020-01-16 13:37:19 -05:00
|
|
|
#include "freertos/FreeRTOS.h"
|
|
|
|
#include <esp_types.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "unity.h"
|
|
|
|
#include "esp_attr.h"
|
|
|
|
#include "esp_heap_caps.h"
|
2022-09-27 04:51:54 -04:00
|
|
|
#include "esp_log.h"
|
2020-01-16 13:37:19 -05:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <sys/param.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
2021-01-28 06:09:49 -05:00
|
|
|
//This test only makes sense with poisoning disabled (light or comprehensive)
|
|
|
|
#if !defined(CONFIG_HEAP_POISONING_COMPREHENSIVE) && !defined(CONFIG_HEAP_POISONING_LIGHT)
|
2020-01-16 13:37:19 -05:00
|
|
|
|
|
|
|
#define NUM_POINTERS 128
|
2022-09-27 04:51:54 -04:00
|
|
|
#define ITERATIONS 5000
|
|
|
|
|
|
|
|
static const char *TAG = "test_heap";
|
2020-01-16 13:37:19 -05:00
|
|
|
|
|
|
|
TEST_CASE("Heap many random allocations timings", "[heap]")
|
|
|
|
{
|
|
|
|
void *p[NUM_POINTERS] = { 0 };
|
|
|
|
size_t s[NUM_POINTERS] = { 0 };
|
|
|
|
|
|
|
|
uint32_t cycles_before;
|
|
|
|
uint64_t alloc_time_average = 0;
|
|
|
|
uint64_t free_time_average = 0;
|
|
|
|
uint64_t realloc_time_average = 0;
|
|
|
|
|
|
|
|
for (int i = 0; i < ITERATIONS; i++) {
|
2022-09-19 05:46:55 -04:00
|
|
|
uint8_t n = (uint32_t)rand() % NUM_POINTERS;
|
2020-01-16 13:37:19 -05:00
|
|
|
|
2022-09-27 04:51:54 -04:00
|
|
|
if (i % 4 == 0) {
|
2020-01-16 13:37:19 -05:00
|
|
|
/* 1 in 4 iterations, try to realloc the buffer instead
|
|
|
|
of using malloc/free
|
|
|
|
*/
|
2022-09-19 05:46:55 -04:00
|
|
|
size_t new_size = (uint32_t)rand() % 1024;
|
2020-11-10 02:40:01 -05:00
|
|
|
|
2020-01-16 13:37:19 -05:00
|
|
|
cycles_before = portGET_RUN_TIME_COUNTER_VALUE();
|
|
|
|
void *new_p = heap_caps_realloc(p[n], new_size, MALLOC_CAP_DEFAULT);
|
|
|
|
realloc_time_average = portGET_RUN_TIME_COUNTER_VALUE() - cycles_before;
|
2020-11-10 02:40:01 -05:00
|
|
|
|
2022-09-27 04:51:54 -04:00
|
|
|
ESP_LOGD(TAG, "realloc %p -> %p (%zu -> %zu) time spent cycles: %lld \n", p[n], new_p, s[n], new_size, realloc_time_average);
|
2020-01-16 13:37:19 -05:00
|
|
|
heap_caps_check_integrity(MALLOC_CAP_DEFAULT, true);
|
|
|
|
if (new_size == 0 || new_p != NULL) {
|
|
|
|
p[n] = new_p;
|
|
|
|
s[n] = new_size;
|
|
|
|
if (new_size > 0) {
|
|
|
|
memset(p[n], n, new_size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (p[n] != NULL) {
|
|
|
|
if (s[n] > 0) {
|
|
|
|
/* Verify pre-existing contents of p[n] */
|
|
|
|
uint8_t compare[s[n]];
|
|
|
|
memset(compare, n, s[n]);
|
|
|
|
TEST_ASSERT(( memcmp(compare, p[n], s[n]) == 0 ));
|
|
|
|
}
|
|
|
|
TEST_ASSERT(heap_caps_check_integrity(MALLOC_CAP_DEFAULT, true));
|
2020-11-10 02:40:01 -05:00
|
|
|
|
2020-01-16 13:37:19 -05:00
|
|
|
cycles_before = portGET_RUN_TIME_COUNTER_VALUE();
|
|
|
|
heap_caps_free(p[n]);
|
|
|
|
free_time_average = portGET_RUN_TIME_COUNTER_VALUE() - cycles_before;
|
|
|
|
|
2022-09-27 04:51:54 -04:00
|
|
|
ESP_LOGD(TAG, "freed %p (%zu) time spent cycles: %lld\n", p[n], s[n], free_time_average);
|
2020-01-16 13:37:19 -05:00
|
|
|
|
|
|
|
if (!heap_caps_check_integrity(MALLOC_CAP_DEFAULT, true)) {
|
|
|
|
printf("FAILED iteration %d after freeing %p\n", i, p[n]);
|
|
|
|
heap_caps_dump(MALLOC_CAP_DEFAULT);
|
|
|
|
TEST_ASSERT(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
s[n] = rand() % 1024;
|
|
|
|
heap_caps_check_integrity(MALLOC_CAP_DEFAULT, true);
|
|
|
|
cycles_before = portGET_RUN_TIME_COUNTER_VALUE();
|
|
|
|
p[n] = heap_caps_malloc(s[n], MALLOC_CAP_DEFAULT);
|
|
|
|
alloc_time_average = portGET_RUN_TIME_COUNTER_VALUE() - cycles_before;
|
2020-11-10 02:40:01 -05:00
|
|
|
|
2022-09-27 04:51:54 -04:00
|
|
|
ESP_LOGD(TAG, "malloc %p (%zu) time spent cycles: %lld \n", p[n], s[n], alloc_time_average);
|
2020-01-16 13:37:19 -05:00
|
|
|
|
|
|
|
if (!heap_caps_check_integrity(MALLOC_CAP_DEFAULT, true)) {
|
|
|
|
printf("FAILED iteration %d after mallocing %p (%zu bytes)\n", i, p[n], s[n]);
|
|
|
|
heap_caps_dump(MALLOC_CAP_DEFAULT);
|
|
|
|
TEST_ASSERT(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (p[n] != NULL) {
|
|
|
|
memset(p[n], n, s[n]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < NUM_POINTERS; i++) {
|
|
|
|
cycles_before = portGET_RUN_TIME_COUNTER_VALUE();
|
|
|
|
heap_caps_free( p[i]);
|
|
|
|
free_time_average = portGET_RUN_TIME_COUNTER_VALUE() - cycles_before;
|
|
|
|
|
|
|
|
if (!heap_caps_check_integrity(MALLOC_CAP_DEFAULT, true)) {
|
|
|
|
printf("FAILED during cleanup after freeing %p\n", p[i]);
|
|
|
|
heap_caps_dump(MALLOC_CAP_DEFAULT);
|
|
|
|
TEST_ASSERT(0);
|
|
|
|
}
|
|
|
|
}
|
2020-11-10 02:40:01 -05:00
|
|
|
|
2020-01-16 13:37:19 -05:00
|
|
|
TEST_ASSERT(heap_caps_check_integrity(MALLOC_CAP_DEFAULT, true));
|
|
|
|
}
|
2020-11-10 02:40:01 -05:00
|
|
|
#endif
|