mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-10-31 21:14:37 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			109 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			109 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include "freertos/FreeRTOS.h"
 | |
| #include <esp_types.h>
 | |
| #include <stdio.h>
 | |
| #include "unity.h"
 | |
| #include "esp_attr.h"
 | |
| #include "esp_heap_caps.h"
 | |
| #include <stdlib.h>
 | |
| #include <sys/param.h>
 | |
| #include <string.h>
 | |
| #include <test_utils.h>
 | |
| 
 | |
| //This test only makes sense with poisoning disabled (light or comprehensive)
 | |
| #if !defined(CONFIG_HEAP_POISONING_COMPREHENSIVE) && !defined(CONFIG_HEAP_POISONING_LIGHT)
 | |
| 
 | |
| #define NUM_POINTERS 128
 | |
| #define ITERATIONS 10000
 | |
| 
 | |
| 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++) {
 | |
|         uint8_t n = esp_random() % NUM_POINTERS;
 | |
| 
 | |
|         if (esp_random() % 4 == 0) {
 | |
|             /* 1 in 4 iterations, try to realloc the buffer instead
 | |
|                of using malloc/free
 | |
|             */
 | |
|             size_t new_size = esp_random() % 1024;
 | |
| 
 | |
|             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;
 | |
| 
 | |
|             printf("realloc %p -> %p (%zu -> %zu) time spent cycles: %lld \n", p[n], new_p, s[n], new_size, realloc_time_average);
 | |
|             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));
 | |
| 
 | |
|             cycles_before = portGET_RUN_TIME_COUNTER_VALUE();
 | |
|             heap_caps_free(p[n]);
 | |
|             free_time_average = portGET_RUN_TIME_COUNTER_VALUE() - cycles_before;
 | |
| 
 | |
|             printf("freed %p (%zu) time spent cycles: %lld\n", p[n], s[n], free_time_average);
 | |
| 
 | |
|             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;
 | |
| 
 | |
|         printf("malloc %p (%zu) time spent cycles: %lld \n", p[n], s[n], alloc_time_average);
 | |
| 
 | |
|         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);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     TEST_ASSERT(heap_caps_check_integrity(MALLOC_CAP_DEFAULT, true));
 | |
| }
 | |
| #endif
 | 
