1 // Copyright 2024 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 #pragma once 15 16 #include <cstdint> 17 18 #include "pw_allocator/allocator.h" 19 #include "pw_bytes/span.h" 20 #include "pw_malloc/config.h" 21 #include "pw_preprocessor/util.h" 22 23 namespace pw::malloc { 24 25 /// Sets the memory to be used by the system allocator. 26 /// 27 /// A backend can implement this method to provide the allocator returned by 28 /// `GetSystemAllocator` with a region of memory for it to use. 29 /// 30 /// @pre This function must be implemented by the `pw_malloc` backend, but may 31 /// be trivially empty if the backend provides its own storage. 32 /// 33 /// @param heap The region of memory to use as a heap. 34 void InitSystemAllocator(ByteSpan heap); 35 36 /// Sets the memory to be used by the system allocator. 37 /// 38 /// This method provides an alternate interface that may be more convenient to 39 /// call with symbols defined in linker scripts. 40 /// 41 /// @param heap_low_addr The inclusive start of the region of memory to use 42 /// as a heap. This MUST be less than `heap_high_addr`. 43 /// @param heap The exclusive end of the region of memory to use as 44 /// a heap. This MUST be less than `heap_high_addr`. 45 void InitSystemAllocator(void* heap_low_addr, void* heap_high_addr); 46 47 /// Sets the memory to be used by the system allocator. 48 /// 49 /// This method is a generic version of `InitSystemAllocator` that works with 50 /// allocator types that have an `Init(ByteSpan)` method. It can be used to 51 /// implement `InitSystemAllocator` for specific pw_malloc backends. 52 /// 53 /// This method enforces the requirement that it is only called once. 54 template <typename AllocatorType> 55 void InitSystemAllocator(ByteSpan heap); 56 57 } // namespace pw::malloc 58 59 #if __cplusplus 60 PW_EXTERN_C_START 61 #endif 62 63 /// Legacy name for `pw::malloc::InitSystemAllocator`. 64 void pw_MallocInit(uint8_t* heap_low_addr, uint8_t* heap_high_addr); 65 66 #if __cplusplus 67 PW_EXTERN_C_END 68 #endif 69 70 namespace pw::malloc { 71 72 /// Returns the system allocator. 73 /// 74 /// This function must be implemented to return a pointer to an allocator with a 75 /// global lifetime. The returned allocator must be initialized and ready to 76 /// use. The facade will call this function at most once. 77 /// 78 /// Backends may either implement this function directly with a concrete 79 /// allocator type, or delegate its implementation to consumers to allow them to 80 /// provide their own allocator types. Backends that implement it directly 81 /// should use `pw_malloc_Init` to provide the region from which to allocate 82 /// memory. 83 /// 84 /// @pre This function must be implemented by the `pw_malloc` backend. 85 Allocator* GetSystemAllocator(); 86 87 /// Returns the metrics for the system allocator using the configured type. 88 const PW_MALLOC_METRICS_TYPE& GetSystemMetrics(); 89 90 // Tmplate method implementations. 91 92 template <typename AllocatorType> InitSystemAllocator(ByteSpan heap)93void InitSystemAllocator(ByteSpan heap) { 94 static bool initialized = false; 95 PW_ASSERT(!initialized); 96 auto* allocator = static_cast<AllocatorType*>(GetSystemAllocator()); 97 allocator->Init(heap); 98 initialized = true; 99 } 100 101 } // namespace pw::malloc 102