|
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