test_allocator_timings.c 3.7 KB

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