multi_heap_platform.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /*
  2. * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #pragma once
  7. #ifdef MULTI_HEAP_FREERTOS
  8. #include "freertos/FreeRTOS.h"
  9. #include "sdkconfig.h"
  10. #include "esp_rom_sys.h"
  11. #include <assert.h>
  12. typedef portMUX_TYPE multi_heap_lock_t;
  13. /* Because malloc/free can happen inside an ISR context,
  14. we need to use portmux spinlocks here not RTOS mutexes */
  15. #define MULTI_HEAP_LOCK(PLOCK) do { \
  16. if((PLOCK) != NULL) { \
  17. portENTER_CRITICAL_SAFE((PLOCK)); \
  18. } \
  19. } while(0)
  20. #define MULTI_HEAP_UNLOCK(PLOCK) do { \
  21. if ((PLOCK) != NULL) { \
  22. portEXIT_CRITICAL_SAFE((PLOCK)); \
  23. } \
  24. } while(0)
  25. #define MULTI_HEAP_LOCK_INIT(PLOCK) do { \
  26. portMUX_INITIALIZE((PLOCK)); \
  27. } while(0)
  28. #define MULTI_HEAP_LOCK_STATIC_INITIALIZER portMUX_INITIALIZER_UNLOCKED
  29. /* Not safe to use std i/o while in a portmux critical section,
  30. can deadlock, so we use the ROM equivalent functions. */
  31. #define MULTI_HEAP_PRINTF esp_rom_printf
  32. #define MULTI_HEAP_STDERR_PRINTF(MSG, ...) esp_rom_printf(MSG, __VA_ARGS__)
  33. inline static void multi_heap_assert(bool condition, const char *format, int line, intptr_t address)
  34. {
  35. /* Can't use libc assert() here as it calls printf() which can cause another malloc() for a newlib lock.
  36. Also, it's useful to be able to print the memory address where corruption was detected.
  37. */
  38. #ifndef NDEBUG
  39. if(!condition) {
  40. #ifndef CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT
  41. esp_rom_printf(format, line, address);
  42. #endif // CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT
  43. abort();
  44. }
  45. #else // NDEBUG
  46. (void) condition;
  47. #endif // NDEBUG
  48. }
  49. #define MULTI_HEAP_ASSERT(CONDITION, ADDRESS) \
  50. multi_heap_assert((CONDITION), "CORRUPT HEAP: multi_heap.c:%d detected at 0x%08x\n", \
  51. __LINE__, (intptr_t)(ADDRESS))
  52. #ifdef CONFIG_HEAP_TASK_TRACKING
  53. #include <freertos/task.h>
  54. #define MULTI_HEAP_SET_BLOCK_OWNER(HEAD) *((TaskHandle_t*)HEAD) = xTaskGetCurrentTaskHandle()
  55. #define MULTI_HEAP_GET_BLOCK_OWNER(HEAD) *((TaskHandle_t*)HEAD)
  56. #define MULTI_HEAP_ADD_BLOCK_OWNER_OFFSET(HEAD) ((TaskHandle_t*)(HEAD) + 1)
  57. #define MULTI_HEAP_REMOVE_BLOCK_OWNER_OFFSET(HEAD) ((TaskHandle_t*)(HEAD) - 1)
  58. #define MULTI_HEAP_ADD_BLOCK_OWNER_SIZE(SIZE) ((SIZE) + sizeof(TaskHandle_t))
  59. #define MULTI_HEAP_REMOVE_BLOCK_OWNER_SIZE(SIZE) ((SIZE) - sizeof(TaskHandle_t))
  60. #define MULTI_HEAP_BLOCK_OWNER_SIZE() sizeof(TaskHandle_t)
  61. #else
  62. #define MULTI_HEAP_SET_BLOCK_OWNER(HEAD)
  63. #define MULTI_HEAP_GET_BLOCK_OWNER(HEAD) (NULL)
  64. #define MULTI_HEAP_ADD_BLOCK_OWNER_OFFSET(HEAD) (HEAD)
  65. #define MULTI_HEAP_REMOVE_BLOCK_OWNER_OFFSET(HEAD) (HEAD)
  66. #define MULTI_HEAP_ADD_BLOCK_OWNER_SIZE(SIZE) (SIZE)
  67. #define MULTI_HEAP_REMOVE_BLOCK_OWNER_SIZE(SIZE) (SIZE)
  68. #define MULTI_HEAP_BLOCK_OWNER_SIZE() 0
  69. #endif // CONFIG_HEAP_TASK_TRACKING
  70. #else // MULTI_HEAP_FREERTOS
  71. #include <assert.h>
  72. #define MULTI_HEAP_PRINTF printf
  73. #define MULTI_HEAP_STDERR_PRINTF(MSG, ...) fprintf(stderr, MSG, __VA_ARGS__)
  74. #define MULTI_HEAP_LOCK(PLOCK) (void) (PLOCK)
  75. #define MULTI_HEAP_UNLOCK(PLOCK) (void) (PLOCK)
  76. #define MULTI_HEAP_LOCK_INIT(PLOCK) (void) (PLOCK)
  77. #define MULTI_HEAP_LOCK_STATIC_INITIALIZER 0
  78. #define MULTI_HEAP_ASSERT(CONDITION, ADDRESS) assert((CONDITION) && "Heap corrupt")
  79. #define MULTI_HEAP_BLOCK_OWNER
  80. #define MULTI_HEAP_SET_BLOCK_OWNER(HEAD)
  81. #define MULTI_HEAP_GET_BLOCK_OWNER(HEAD) (NULL)
  82. #endif // MULTI_HEAP_FREERTOS