FastLED 3.9.15
Loading...
Searching...
No Matches
allocator.cpp
Go to the documentation of this file.
1#include <stdlib.h>
2
3#include "fl/allocator.h"
4#include "fl/namespace.h"
5#include "fl/int.h"
6#include "fl/thread_local.h"
7
8#ifdef ESP32
9#include "esp_heap_caps.h"
10#include "esp_system.h"
11#endif
12
13namespace fl {
14
15namespace {
16
17#ifdef ESP32
18// On esp32, attempt to always allocate in psram first.
19void *DefaultAlloc(fl::size size) {
20 void *out = heap_caps_malloc(size, MALLOC_CAP_SPIRAM);
21 if (out == nullptr) {
22 // Fallback to default allocator.
23 out = heap_caps_malloc(size, MALLOC_CAP_DEFAULT);
24 }
25 return out;
26}
27void DefaultFree(void *ptr) { heap_caps_free(ptr); }
28#else
29void *DefaultAlloc(fl::size size) { return malloc(size); }
30void DefaultFree(void *ptr) { free(ptr); }
31#endif
32
33void *(*Alloc)(fl::size) = DefaultAlloc;
34void (*Dealloc)(void *) = DefaultFree;
35
36#if defined(FASTLED_TESTING)
37// Test hook interface pointer
38MallocFreeHook* gMallocFreeHook = nullptr;
39
40int& tls_reintrancy_count() {
41 static fl::ThreadLocal<int> enabled;
42 return enabled.access();
43}
44
45struct MemoryGuard {
46 int& reintrancy_count;
47 MemoryGuard(): reintrancy_count(tls_reintrancy_count()) {
48 reintrancy_count++;
49 }
50 ~MemoryGuard() {
51 reintrancy_count--;
52 }
53 bool enabled() const {
54 return reintrancy_count <= 1;
55 }
56};
57
58#endif
59
60} // namespace
61
62#if defined(FASTLED_TESTING)
63void SetMallocFreeHook(MallocFreeHook* hook) {
64 gMallocFreeHook = hook;
65}
66
67void ClearMallocFreeHook() {
68 gMallocFreeHook = nullptr;
69}
70#endif
71
72void SetPSRamAllocator(void *(*alloc)(fl::size), void (*free)(void *)) {
73 Alloc = alloc;
74 Dealloc = free;
75}
76
77void *PSRamAllocate(fl::size size, bool zero) {
78
79 void *ptr = Alloc(size);
80 if (ptr && zero) {
81 memset(ptr, 0, size);
82 }
83
84#if defined(FASTLED_TESTING)
85 if (gMallocFreeHook && ptr) {
86 MemoryGuard allows_hook;
87 if (allows_hook.enabled()) {
88 gMallocFreeHook->onMalloc(ptr, size);
89 }
90 }
91#endif
92
93 return ptr;
94}
95
96void PSRamDeallocate(void *ptr) {
97#if defined(FASTLED_TESTING)
98 if (gMallocFreeHook && ptr) {
99 // gMallocFreeHook->onFree(ptr);
100 MemoryGuard allows_hook;
101 if (allows_hook.enabled()) {
102 gMallocFreeHook->onFree(ptr);
103 }
104 }
105#endif
106
107 Dealloc(ptr);
108}
109
110void* Malloc(fl::size size) {
111 void* ptr = Alloc(size);
112
113#if defined(FASTLED_TESTING)
114 if (gMallocFreeHook && ptr) {
115 MemoryGuard allows_hook;
116 if (allows_hook.enabled()) {
117 gMallocFreeHook->onMalloc(ptr, size);
118 }
119 }
120#endif
121
122 return ptr;
123}
124
125void Free(void *ptr) {
126#if defined(FASTLED_TESTING)
127 if (gMallocFreeHook && ptr) {
128 MemoryGuard allows_hook;
129 if (allows_hook.enabled()) {
130 gMallocFreeHook->onFree(ptr);
131 }
132 }
133#endif
134
135 Dealloc(ptr);
136}
137
138} // namespace fl
Implements the FastLED namespace macros.
void Free(void *ptr)
ThreadLocalFake< T > ThreadLocal
void SetPSRamAllocator(void *(*alloc)(fl::size), void(*free)(void *))
Definition allocator.cpp:72
void PSRamDeallocate(void *ptr)
Definition allocator.cpp:96
void * Malloc(fl::size size)
void * PSRamAllocate(fl::size size, bool zero)
Definition allocator.cpp:77
IMPORTANT!
Definition crgb.h:20