1 /*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef CHRE_UTIL_CONTAINER_SUPPORT_H_
18 #define CHRE_UTIL_CONTAINER_SUPPORT_H_
19
20 /**
21 * @file Provides replacements for macros and functions that are normally
22 * provided by the CHRE framework implementation. These portable implementations
23 * are implemented using the CHRE API rather than private system APIs.
24 */
25
26 #if defined CHRE_IS_NANOAPP_BUILD
27
28 #include "chre/util/nanoapp/assert.h"
29 #include "chre_api/chre.h"
30
31 #ifdef CHRE_STANDALONE_POSIX_ALIGNED_ALLOC
32 #include <stdlib.h>
33 #else
34 #include "chre/util/always_false.h"
35 #endif // CHRE_STANDALONE_POSIX_ALIGNED_ALLOC
36
37 namespace chre {
38
39 /**
40 * Provides the memoryAlloc function that is normally provided by the CHRE
41 * runtime. It maps into chreHeapAlloc.
42 *
43 * @param size the size of the allocation to make.
44 * @return a pointer to allocated memory or nullptr if allocation failed.
45 */
memoryAlloc(size_t size)46 inline void *memoryAlloc(size_t size) {
47 return chreHeapAlloc(static_cast<uint32_t>(size));
48 }
49
50 /**
51 * Returns memory of suitable alignment to hold an array of the given object
52 * type, which may exceed alignment of std::max_align_t and therefore cannot
53 * use memoryAlloc().
54 *
55 * @param count the number of elements to allocate.
56 * @return a pointer to allocated memory or nullptr if allocation failed.
57 */
58 template <typename T>
memoryAlignedAllocArray(size_t count)59 inline T *memoryAlignedAllocArray([[maybe_unused]] size_t count) {
60 #ifdef CHRE_STANDALONE_POSIX_ALIGNED_ALLOC
61 void *ptr;
62 int result = posix_memalign(&ptr, alignof(T), sizeof(T) * count);
63 if (result != 0) {
64 ptr = nullptr;
65 }
66 return static_cast<T *>(ptr);
67 #else
68 static_assert(AlwaysFalse<T>::value,
69 "memoryAlignedAlloc is unsupported on this platform");
70 return nullptr;
71 #endif // CHRE_STANDALONE_POSIX_ALIGNED_ALLOC
72 }
73
74 /**
75 * Returns memory of suitable alignment to hold a given object of the
76 * type T, which may exceed alignment of std::max_align_t and therefore cannot
77 * use memoryAlloc().
78 *
79 * @return a pointer to allocated memory or nullptr if allocation failed.
80 */
81 template <typename T>
memoryAlignedAlloc()82 inline T *memoryAlignedAlloc() {
83 return memoryAlignedAllocArray<T>(/* count= */ 1);
84 }
85
86 /**
87 * Provides the memoryFree function that is normally provided by the CHRE
88 * runtime. It maps into chreHeapFree.
89 *
90 * @param pointer the allocation to release.
91 */
memoryFree(void * pointer)92 inline void memoryFree(void *pointer) {
93 chreHeapFree(pointer);
94 }
95
96 } // namespace chre
97
98 #elif defined CHRE_IS_HOST_BUILD
99
100 #include "chre/util/host/assert.h"
101
102 namespace chre {
103
104 /**
105 * Provides the memoryAlloc function that is normally provided by the CHRE
106 * runtime. It maps into malloc.
107 *
108 * @param size the size of the allocation to make.
109 * @return a pointer to allocated memory or nullptr if allocation failed.
110 */
memoryAlloc(size_t size)111 inline void *memoryAlloc(size_t size) {
112 return malloc(size);
113 }
114
115 /**
116 * Returns memory of suitable alignment to hold an array of the given object
117 * type, which may exceed alignment of std::max_align_t and therefore cannot
118 * use memoryAlloc().
119 *
120 * @param count the number of elements to allocate.
121 * @return a pointer to allocated memory or nullptr if allocation failed.
122 */
123 template <typename T>
memoryAlignedAllocArray(size_t count)124 inline T *memoryAlignedAllocArray(size_t count) {
125 void *ptr;
126 int result = posix_memalign(&ptr, alignof(T), sizeof(T) * count);
127 if (result != 0) {
128 ptr = nullptr;
129 }
130 return static_cast<T *>(ptr);
131 }
132
133 /**
134 * Returns memory of suitable alignment to hold a given object of the
135 * type T, which may exceed alignment of std::max_align_t and therefore cannot
136 * use memoryAlloc().
137 *
138 * @return a pointer to allocated memory or nullptr if allocation failed.
139 */
140 template <typename T>
memoryAlignedAlloc()141 inline T *memoryAlignedAlloc() {
142 return memoryAlignedAllocArray<T>(/* count= */1);
143 }
144
145 /**
146 * Provides the memoryFree function that is normally provided by the CHRE
147 * runtime. It maps into free.
148 *
149 * @param pointer the allocation to release.
150 */
memoryFree(void * pointer)151 inline void memoryFree(void *pointer) {
152 free(pointer);
153 }
154
155 } // namespace chre
156
157 #else
158 #include "chre/platform/assert.h"
159 #include "chre/platform/memory.h"
160 #endif // CHRE_IS_NANOAPP_BUILD
161
162 #endif // CHRE_UTIL_CONTAINER_SUPPORT_H_
163