1 // Copyright 2020 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
15 #include <span>
16
17 #include "pw_allocator/freelist_heap.h"
18 #include "pw_malloc/malloc.h"
19 #include "pw_preprocessor/compiler.h"
20 #include "pw_preprocessor/util.h"
21
22 namespace {
23 std::aligned_storage_t<sizeof(pw::allocator::FreeListHeapBuffer<>),
24 alignof(pw::allocator::FreeListHeapBuffer<>)>
25 buf;
26 } // namespace
27 pw::allocator::FreeListHeapBuffer<>* pw_freelist_heap;
28
29 #if __cplusplus
30 extern "C" {
31 #endif // __cplusplus
32 // Define the global heap variables.
pw_MallocInit(uint8_t * heap_low_addr,uint8_t * heap_high_addr)33 void pw_MallocInit(uint8_t* heap_low_addr, uint8_t* heap_high_addr) {
34 std::span<std::byte> pw_allocator_freelist_raw_heap =
35 std::span(reinterpret_cast<std::byte*>(heap_low_addr),
36 heap_high_addr - heap_low_addr);
37 pw_freelist_heap = new (&buf)
38 pw::allocator::FreeListHeapBuffer(pw_allocator_freelist_raw_heap);
39 }
40
41 // Wrapper functions for malloc, free, realloc and calloc.
42 // With linker options "-Wl --wrap=<function name>", linker will link
43 // "__wrap_<function name>" with "<function_name>", and calling
44 // "<function name>" will call "__wrap_<function name>" instead
45 // Linker options are set in a config in "pw_malloc:pw_malloc_config".
__wrap_malloc(size_t size)46 void* __wrap_malloc(size_t size) { return pw_freelist_heap->Allocate(size); }
47
__wrap_free(void * ptr)48 void __wrap_free(void* ptr) { pw_freelist_heap->Free(ptr); }
49
__wrap_realloc(void * ptr,size_t size)50 void* __wrap_realloc(void* ptr, size_t size) {
51 return pw_freelist_heap->Realloc(ptr, size);
52 }
53
__wrap_calloc(size_t num,size_t size)54 void* __wrap_calloc(size_t num, size_t size) {
55 return pw_freelist_heap->Calloc(num, size);
56 }
57
__wrap__malloc_r(struct _reent *,size_t size)58 void* __wrap__malloc_r(struct _reent*, size_t size) {
59 return pw_freelist_heap->Allocate(size);
60 }
61
__wrap__free_r(struct _reent *,void * ptr)62 void __wrap__free_r(struct _reent*, void* ptr) { pw_freelist_heap->Free(ptr); }
63
__wrap__realloc_r(struct _reent *,void * ptr,size_t size)64 void* __wrap__realloc_r(struct _reent*, void* ptr, size_t size) {
65 return pw_freelist_heap->Realloc(ptr, size);
66 }
67
__wrap__calloc_r(struct _reent *,size_t num,size_t size)68 void* __wrap__calloc_r(struct _reent*, size_t num, size_t size) {
69 return pw_freelist_heap->Calloc(num, size);
70 }
71 #if __cplusplus
72 }
73 #endif // __cplusplus
74