|
171 | 171 | using ssize_t = ptrdiff_t; |
172 | 172 | #endif |
173 | 173 |
|
174 | | -/** |
175 | | - * Platform-specific aligned memory allocation and deallocation. |
176 | | - * |
177 | | - * Usage: |
178 | | - * void* ptr = ET_ALIGNED_ALLOC(alignment, size); |
179 | | - * // use ptr... |
180 | | - * ET_ALIGNED_FREE(ptr); |
181 | | - * |
182 | | - * Note: alignment must be a power of 2 and size must be an integral multiple of |
183 | | - * alignment. |
184 | | - */ |
185 | | -#if defined(_MSC_VER) |
186 | | -#include <malloc.h> |
187 | | -#define ET_ALIGNED_ALLOC(alignment, size) \ |
188 | | - _aligned_malloc(((size + alignment - 1) & ~(alignment - 1)), (alignment)) |
189 | | -#define ET_ALIGNED_FREE(ptr) _aligned_free(ptr) |
190 | | -#elif defined(__APPLE__) |
191 | | -#include <stdlib.h> // For posix_memalign and free |
192 | | -inline void* et_apple_aligned_alloc(size_t alignment, size_t size) { |
193 | | - void* ptr = nullptr; |
194 | | - // The address of the allocated memory must be a multiple of sizeof(void*). |
195 | | - if (alignment < sizeof(void*)) { |
196 | | - alignment = sizeof(void*); |
197 | | - } |
198 | | - if (posix_memalign( |
199 | | - &ptr, alignment, (size + alignment - 1) & ~(alignment - 1)) != 0) { |
200 | | - return nullptr; |
201 | | - } |
202 | | - return ptr; |
203 | | -} |
204 | | -#define ET_ALIGNED_ALLOC(alignment, size) \ |
205 | | - et_apple_aligned_alloc((alignment), (size)) |
206 | | -#define ET_ALIGNED_FREE(ptr) free(ptr) |
207 | | -#elif __has_builtin(__builtin_aligned_alloc) || defined(_ISOC11_SOURCE) |
208 | | -// Linux and posix systems that support aligned_alloc and are >= C++17. |
209 | | -#include <cstdlib> |
210 | | -#define ET_ALIGNED_ALLOC(alignment, size) \ |
211 | | - ::aligned_alloc(alignment, (size + alignment - 1) & ~(alignment - 1)) |
212 | | -#define ET_ALIGNED_FREE(ptr) free(ptr) |
213 | | -#else |
214 | | -// If the platform doesn't support aligned_alloc, fallback to malloc. |
215 | | -#include <stdint.h> |
216 | | -#include <cstdlib> |
217 | | -inline void* et_aligned_malloc(size_t alignment, size_t size) { |
218 | | - // Place to store the offset to the original pointer. |
219 | | - size_t offset_size = sizeof(uint16_t); |
220 | | - |
221 | | - // Malloc extra space for offset + alignment. |
222 | | - size_t alloc_size = size + offset_size + alignment - 1; |
223 | | - void* ptr = std::malloc(alloc_size); |
224 | | - |
225 | | - if (ptr == nullptr) { |
226 | | - // Malloc failed. |
227 | | - return nullptr; |
228 | | - } |
229 | | - |
230 | | - uintptr_t addr = reinterpret_cast<uintptr_t>(ptr); |
231 | | - // Align the address past addr + offset_size bytes. |
232 | | - // This provides space to store the offset before the aligned pointer. |
233 | | - addr = addr + offset_size; |
234 | | - uintptr_t aligned_ptr = (addr + alignment - 1) & ~(alignment - 1); |
235 | | - |
236 | | - // Check that alignment didn't overflow the buffer. |
237 | | - if (reinterpret_cast<uintptr_t>(aligned_ptr) + size > |
238 | | - reinterpret_cast<uintptr_t>(ptr) + alloc_size) { |
239 | | - std::free(ptr); |
240 | | - return nullptr; |
241 | | - } |
242 | | - |
243 | | - // Store the offset to the original pointer. |
244 | | - // Used to free the original allocated buffer. |
245 | | - *(reinterpret_cast<uint16_t*>(aligned_ptr) - 1) = |
246 | | - (uint16_t)(reinterpret_cast<uintptr_t>(aligned_ptr) - |
247 | | - reinterpret_cast<uintptr_t>(ptr)); |
248 | | - |
249 | | - return reinterpret_cast<uint16_t*>(aligned_ptr); |
250 | | -} |
251 | | - |
252 | | -inline void et_aligned_free(void* ptr) { |
253 | | - if (ptr == nullptr) { |
254 | | - return; |
255 | | - } |
256 | | - |
257 | | - // Get the original pointer using the offset. |
258 | | - uint16_t* original_ptr = reinterpret_cast<uint16_t*>( |
259 | | - reinterpret_cast<uintptr_t>(ptr) - |
260 | | - *(reinterpret_cast<uint16_t*>(ptr) - 1)); |
261 | | - std::free(original_ptr); |
262 | | -} |
263 | | - |
264 | | -#define ET_ALIGNED_ALLOC(alignment, size) et_aligned_malloc((alignment), (size)) |
265 | | -#define ET_ALIGNED_FREE(ptr) et_aligned_free(ptr) |
266 | | - |
267 | | -#endif |
268 | | - |
269 | 174 | // DEPRECATED: Use the non-underscore-prefixed versions instead. |
270 | 175 | // TODO(T199005537): Remove these once all users have stopped using them. |
271 | 176 | #define __ET_DEPRECATED ET_DEPRECATED |
|
0 commit comments