| // Copyright 2022 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef TOOLS_UTIL_ALIGNED_ALLOC_H_ | 
 | #define TOOLS_UTIL_ALIGNED_ALLOC_H_ | 
 |  | 
 | #ifdef __APPLE__ | 
 | #include <Availability.h> | 
 | #endif | 
 |  | 
 | #include <cstdlib> | 
 |  | 
 | #define IMPL_ALIGNED_ALLOC_CXX17 1 | 
 | #define IMPL_ALIGNED_ALLOC_WIN32 2 | 
 | #define IMPL_ALIGNED_ALLOC_POSIX 3 | 
 |  | 
 | #ifndef IMPL_ALIGNED_ALLOC | 
 | #ifdef _WIN32 | 
 | #define IMPL_ALIGNED_ALLOC IMPL_ALIGNED_ALLOC_WIN32 | 
 | #elif defined(__APPLE__) | 
 | // Note that aligned_alloc() is only available at runtime starting from | 
 | // OSX 10.15, so use posix_memalign() instead which is more portable. | 
 | #define IMPL_ALIGNED_ALLOC IMPL_ALIGNED_ALLOC_POSIX | 
 | #else | 
 | #define IMPL_ALIGNED_ALLOC IMPL_ALIGNED_ALLOC_CXX17 | 
 | #endif | 
 | #endif | 
 |  | 
 | #if IMPL_ALIGNED_ALLOC == IMPL_ALIGNED_ALLOC_WIN32 | 
 | #include <malloc.h>  // for _aligned_malloc() and _aligned_free() | 
 | #endif | 
 |  | 
 | #if IMPL_ALIGNED_ALLOC == IMPL_ALIGNED_ALLOC_POSIX | 
 | #include "base/logging.h"  // for CHECK() | 
 | #endif | 
 |  | 
 | // AlignedAlloc<N> provides Alloc() and Free() methods that can be | 
 | // used to allocate and release blocks of heap memory aligned with | 
 | // N bytes. | 
 | // | 
 | // The implementation uses std::aligned_alloc() when it is available, | 
 | // or uses fallbacks otherwise. On Win32, _aligned_malloc() and | 
 | // _aligned_free() are used, while for MacOS releases, ::posix_memaloc() | 
 | // is used. | 
 | template <size_t ALIGNMENT> | 
 | struct AlignedAlloc { | 
 |   static void* Alloc(size_t size) { | 
 |     static_assert((ALIGNMENT & (ALIGNMENT - 1)) == 0, | 
 |                   "ALIGNMENT must be a power of 2"); | 
 | #if IMPL_ALIGNED_ALLOC == IMPL_ALIGNED_ALLOC_WIN32 | 
 |     return _aligned_malloc(size, ALIGNMENT); | 
 | #elif IMPL_ALIGNED_ALLOC == IMPL_ALIGNED_ALLOC_POSIX | 
 |     void* ptr = nullptr; | 
 |     CHECK(!posix_memalign(&ptr, ALIGNMENT, size)); | 
 |     return ptr; | 
 | #else  // IMPL_ALIGNED_ALLOC_CXX17 | 
 |     return std::aligned_alloc(ALIGNMENT, size); | 
 | #endif | 
 |   } | 
 |  | 
 |   static void Free(void* block) { | 
 | #if IMPL_ALIGNED_ALLOC == IMPL_ALIGNED_ALLOC_WIN32 | 
 |     _aligned_free(block); | 
 | #elif IMPL_ALIGNED_ALLOC == IMPL_ALIGNED_ALLOC_POSIX | 
 |     return ::free(block); | 
 | #else | 
 |     // Allocation came from std::aligned_alloc() | 
 |     return std::free(block); | 
 | #endif | 
 |   } | 
 | }; | 
 |  | 
 | #endif  // TOOLS_UTIL_ALIGNED_ALLOC_H_ |