10b57cec5SDimitry Andric /*===---- mm_malloc.h - Allocating and Freeing Aligned Memory Blocks -------=== 20b57cec5SDimitry Andric * 30b57cec5SDimitry Andric * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric * See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric * 70b57cec5SDimitry Andric *===-----------------------------------------------------------------------=== 80b57cec5SDimitry Andric */ 90b57cec5SDimitry Andric 100b57cec5SDimitry Andric #ifndef __MM_MALLOC_H 110b57cec5SDimitry Andric #define __MM_MALLOC_H 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include <stdlib.h> 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric #ifdef _WIN32 160b57cec5SDimitry Andric #include <malloc.h> 170b57cec5SDimitry Andric #else 180b57cec5SDimitry Andric #ifndef __cplusplus 190b57cec5SDimitry Andric extern int posix_memalign(void **__memptr, size_t __alignment, size_t __size); 200b57cec5SDimitry Andric #else 210b57cec5SDimitry Andric // Some systems (e.g. those with GNU libc) declare posix_memalign with an 220b57cec5SDimitry Andric // exception specifier. Via an "egregious workaround" in 230b57cec5SDimitry Andric // Sema::CheckEquivalentExceptionSpec, Clang accepts the following as a valid 240b57cec5SDimitry Andric // redeclaration of glibc's declaration. 250b57cec5SDimitry Andric extern "C" int posix_memalign(void **__memptr, size_t __alignment, size_t __size); 260b57cec5SDimitry Andric #endif 270b57cec5SDimitry Andric #endif 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric #if !(defined(_WIN32) && defined(_mm_malloc)) 300b57cec5SDimitry Andric static __inline__ void *__attribute__((__always_inline__, __nodebug__, 310b57cec5SDimitry Andric __malloc__)) 320b57cec5SDimitry Andric _mm_malloc(size_t __size, size_t __align) 330b57cec5SDimitry Andric { 340b57cec5SDimitry Andric if (__align == 1) { 350b57cec5SDimitry Andric return malloc(__size); 360b57cec5SDimitry Andric } 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric if (!(__align & (__align - 1)) && __align < sizeof(void *)) 390b57cec5SDimitry Andric __align = sizeof(void *); 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric void *__mallocedMemory; 420b57cec5SDimitry Andric #if defined(__MINGW32__) 430b57cec5SDimitry Andric __mallocedMemory = __mingw_aligned_malloc(__size, __align); 440b57cec5SDimitry Andric #elif defined(_WIN32) 450b57cec5SDimitry Andric __mallocedMemory = _aligned_malloc(__size, __align); 460b57cec5SDimitry Andric #else 470b57cec5SDimitry Andric if (posix_memalign(&__mallocedMemory, __align, __size)) 480b57cec5SDimitry Andric return 0; 490b57cec5SDimitry Andric #endif 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric return __mallocedMemory; 520b57cec5SDimitry Andric } 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric static __inline__ void __attribute__((__always_inline__, __nodebug__)) 550b57cec5SDimitry Andric _mm_free(void *__p) 560b57cec5SDimitry Andric { 57e8d8bef9SDimitry Andric #if defined(__MINGW32__) 58e8d8bef9SDimitry Andric __mingw_aligned_free(__p); 59e8d8bef9SDimitry Andric #elif defined(_WIN32) 60e8d8bef9SDimitry Andric _aligned_free(__p); 61e8d8bef9SDimitry Andric #else 620b57cec5SDimitry Andric free(__p); 63e8d8bef9SDimitry Andric #endif 640b57cec5SDimitry Andric } 650b57cec5SDimitry Andric #endif 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric #endif /* __MM_MALLOC_H */ 68