1 #include "freertos/FreeRTOS.h" 2 #include <esp_types.h> 3 #include <stdio.h> 4 #include "unity.h" 5 #include "esp_attr.h" 6 #include "esp_heap_caps.h" 7 #include <stdlib.h> 8 #include <sys/param.h> 9 #include <string.h> 10 #include <test_utils.h> 11 12 //This test only makes sense with poisoning disabled (light or comprehensive) 13 #if !defined(CONFIG_HEAP_POISONING_COMPREHENSIVE) && !defined(CONFIG_HEAP_POISONING_LIGHT) 14 15 #define NUM_POINTERS 128 16 #define ITERATIONS 10000 17 18 TEST_CASE("Heap many random allocations timings", "[heap]") 19 { 20 void *p[NUM_POINTERS] = { 0 }; 21 size_t s[NUM_POINTERS] = { 0 }; 22 23 uint32_t cycles_before; 24 uint64_t alloc_time_average = 0; 25 uint64_t free_time_average = 0; 26 uint64_t realloc_time_average = 0; 27 28 for (int i = 0; i < ITERATIONS; i++) { 29 uint8_t n = esp_random() % NUM_POINTERS; 30 31 if (esp_random() % 4 == 0) { 32 /* 1 in 4 iterations, try to realloc the buffer instead 33 of using malloc/free 34 */ 35 size_t new_size = esp_random() % 1024; 36 37 cycles_before = portGET_RUN_TIME_COUNTER_VALUE(); 38 void *new_p = heap_caps_realloc(p[n], new_size, MALLOC_CAP_DEFAULT); 39 realloc_time_average = portGET_RUN_TIME_COUNTER_VALUE() - cycles_before; 40 41 printf("realloc %p -> %p (%zu -> %zu) time spent cycles: %lld \n", p[n], new_p, s[n], new_size, realloc_time_average); 42 heap_caps_check_integrity(MALLOC_CAP_DEFAULT, true); 43 if (new_size == 0 || new_p != NULL) { 44 p[n] = new_p; 45 s[n] = new_size; 46 if (new_size > 0) { 47 memset(p[n], n, new_size); 48 } 49 } 50 continue; 51 } 52 53 if (p[n] != NULL) { 54 if (s[n] > 0) { 55 /* Verify pre-existing contents of p[n] */ 56 uint8_t compare[s[n]]; 57 memset(compare, n, s[n]); 58 TEST_ASSERT(( memcmp(compare, p[n], s[n]) == 0 )); 59 } 60 TEST_ASSERT(heap_caps_check_integrity(MALLOC_CAP_DEFAULT, true)); 61 62 cycles_before = portGET_RUN_TIME_COUNTER_VALUE(); 63 heap_caps_free(p[n]); 64 free_time_average = portGET_RUN_TIME_COUNTER_VALUE() - cycles_before; 65 66 printf("freed %p (%zu) time spent cycles: %lld\n", p[n], s[n], free_time_average); 67 68 if (!heap_caps_check_integrity(MALLOC_CAP_DEFAULT, true)) { 69 printf("FAILED iteration %d after freeing %p\n", i, p[n]); 70 heap_caps_dump(MALLOC_CAP_DEFAULT); 71 TEST_ASSERT(0); 72 } 73 } 74 75 s[n] = rand() % 1024; 76 heap_caps_check_integrity(MALLOC_CAP_DEFAULT, true); 77 cycles_before = portGET_RUN_TIME_COUNTER_VALUE(); 78 p[n] = heap_caps_malloc(s[n], MALLOC_CAP_DEFAULT); 79 alloc_time_average = portGET_RUN_TIME_COUNTER_VALUE() - cycles_before; 80 81 printf("malloc %p (%zu) time spent cycles: %lld \n", p[n], s[n], alloc_time_average); 82 83 if (!heap_caps_check_integrity(MALLOC_CAP_DEFAULT, true)) { 84 printf("FAILED iteration %d after mallocing %p (%zu bytes)\n", i, p[n], s[n]); 85 heap_caps_dump(MALLOC_CAP_DEFAULT); 86 TEST_ASSERT(0); 87 } 88 89 if (p[n] != NULL) { 90 memset(p[n], n, s[n]); 91 } 92 } 93 94 for (int i = 0; i < NUM_POINTERS; i++) { 95 cycles_before = portGET_RUN_TIME_COUNTER_VALUE(); 96 heap_caps_free( p[i]); 97 free_time_average = portGET_RUN_TIME_COUNTER_VALUE() - cycles_before; 98 99 if (!heap_caps_check_integrity(MALLOC_CAP_DEFAULT, true)) { 100 printf("FAILED during cleanup after freeing %p\n", p[i]); 101 heap_caps_dump(MALLOC_CAP_DEFAULT); 102 TEST_ASSERT(0); 103 } 104 } 105 106 TEST_ASSERT(heap_caps_check_integrity(MALLOC_CAP_DEFAULT, true)); 107 } 108 #endif 109