furi_memmgr_test.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #include "../minunit.h"
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <stdbool.h>
  5. // this test is not accurate, but gives a basic understanding
  6. // that memory management is working fine
  7. // do not include memmgr.h here
  8. // we also test that we are linking against stdlib
  9. extern size_t memmgr_get_free_heap(void);
  10. extern size_t memmgr_get_minimum_free_heap(void);
  11. // current heap managment realization consume:
  12. // X bytes after allocate and 0 bytes after allocate and free,
  13. // where X = sizeof(void*) + sizeof(size_t), look to BlockLink_t
  14. const size_t heap_overhead_max_size = sizeof(void*) + sizeof(size_t);
  15. bool heap_equal(size_t heap_size, size_t heap_size_old) {
  16. // heap borders with overhead
  17. const size_t heap_low = heap_size_old - heap_overhead_max_size;
  18. const size_t heap_high = heap_size_old + heap_overhead_max_size;
  19. // not extact, so we must test it against bigger numbers than "overhead size"
  20. const bool result = ((heap_size >= heap_low) && (heap_size <= heap_high));
  21. // debug allocation info
  22. if(!result) {
  23. printf("\n(hl: %zu) <= (p: %zu) <= (hh: %zu)\n", heap_low, heap_size, heap_high);
  24. }
  25. return result;
  26. }
  27. void test_furi_memmgr() {
  28. size_t heap_size = 0;
  29. size_t heap_size_old = 0;
  30. const int alloc_size = 128;
  31. void* ptr = NULL;
  32. void* original_ptr = NULL;
  33. // do not include furi memmgr.h case
  34. #ifdef FURI_MEMMGR_GUARD
  35. mu_fail("do not link against furi memmgr.h");
  36. #endif
  37. // allocate memory case
  38. heap_size_old = memmgr_get_free_heap();
  39. ptr = malloc(alloc_size);
  40. heap_size = memmgr_get_free_heap();
  41. mu_assert_pointers_not_eq(ptr, NULL);
  42. mu_assert(heap_equal(heap_size, heap_size_old - alloc_size), "allocate failed");
  43. // free memory case
  44. heap_size_old = memmgr_get_free_heap();
  45. free(ptr);
  46. ptr = NULL;
  47. heap_size = memmgr_get_free_heap();
  48. mu_assert(heap_equal(heap_size, heap_size_old + alloc_size), "free failed");
  49. // reallocate memory case
  50. // get filled array with some data
  51. original_ptr = malloc(alloc_size);
  52. mu_assert_pointers_not_eq(original_ptr, NULL);
  53. for(int i = 0; i < alloc_size; i++) {
  54. *(unsigned char*)(original_ptr + i) = i;
  55. }
  56. // malloc array and copy data
  57. ptr = malloc(alloc_size);
  58. mu_assert_pointers_not_eq(ptr, NULL);
  59. memcpy(ptr, original_ptr, alloc_size);
  60. // reallocate array
  61. heap_size_old = memmgr_get_free_heap();
  62. ptr = realloc(ptr, alloc_size * 2);
  63. heap_size = memmgr_get_free_heap();
  64. mu_assert(heap_equal(heap_size, heap_size_old - alloc_size), "reallocate failed");
  65. mu_assert_int_eq(memcmp(original_ptr, ptr, alloc_size), 0);
  66. free(original_ptr);
  67. free(ptr);
  68. // allocate and zero-initialize array (calloc)
  69. original_ptr = malloc(alloc_size);
  70. mu_assert_pointers_not_eq(original_ptr, NULL);
  71. for(int i = 0; i < alloc_size; i++) {
  72. *(unsigned char*)(original_ptr + i) = 0;
  73. }
  74. heap_size_old = memmgr_get_free_heap();
  75. ptr = calloc(1, alloc_size);
  76. heap_size = memmgr_get_free_heap();
  77. mu_assert(heap_equal(heap_size, heap_size_old - alloc_size), "callocate failed");
  78. mu_assert_int_eq(memcmp(original_ptr, ptr, alloc_size), 0);
  79. free(original_ptr);
  80. free(ptr);
  81. }