12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- // Copyright (c) 2012 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 BASE_MEMORY_ALIGNED_MEMORY_H_
- #define BASE_MEMORY_ALIGNED_MEMORY_H_
- #include <stddef.h>
- #include <stdint.h>
- #include <type_traits>
- #include "base/base_export.h"
- #include "base/bits.h"
- #include "base/check.h"
- #include "base/process/process_metrics.h"
- #include "build/build_config.h"
- #if defined(COMPILER_MSVC)
- #include <malloc.h>
- #else
- #include <stdlib.h>
- #endif
- // A runtime sized aligned allocation can be created:
- //
- // float* my_array = static_cast<float*>(AlignedAlloc(size, alignment));
- //
- // // ... later, to release the memory:
- // AlignedFree(my_array);
- //
- // Or using unique_ptr:
- //
- // std::unique_ptr<float, AlignedFreeDeleter> my_array(
- // static_cast<float*>(AlignedAlloc(size, alignment)));
- namespace base {
- // This can be replaced with std::aligned_alloc when we have C++17.
- // Caveat: std::aligned_alloc requires the size parameter be an integral
- // multiple of alignment.
- BASE_EXPORT void* AlignedAlloc(size_t size, size_t alignment);
- inline void AlignedFree(void* ptr) {
- #if defined(COMPILER_MSVC)
- _aligned_free(ptr);
- #else
- free(ptr);
- #endif
- }
- // Deleter for use with unique_ptr. E.g., use as
- // std::unique_ptr<Foo, base::AlignedFreeDeleter> foo;
- struct AlignedFreeDeleter {
- inline void operator()(void* ptr) const {
- AlignedFree(ptr);
- }
- };
- #ifdef __has_builtin
- #define SUPPORTS_BUILTIN_IS_ALIGNED (__has_builtin(__builtin_is_aligned))
- #else
- #define SUPPORTS_BUILTIN_IS_ALIGNED 0
- #endif
- inline bool IsAligned(uintptr_t val, size_t alignment) {
- // If the compiler supports builtin alignment checks prefer them.
- #if SUPPORTS_BUILTIN_IS_ALIGNED
- return __builtin_is_aligned(val, alignment);
- #else
- DCHECK(bits::IsPowerOfTwo(alignment)) << alignment << " is not a power of 2";
- return (val & (alignment - 1)) == 0;
- #endif
- }
- #undef SUPPORTS_BUILTIN_IS_ALIGNED
- inline bool IsAligned(const void* val, size_t alignment) {
- return IsAligned(reinterpret_cast<uintptr_t>(val), alignment);
- }
- template <typename Type>
- inline bool IsPageAligned(Type val) {
- static_assert(std::is_integral<Type>::value || std::is_pointer<Type>::value,
- "Integral or pointer type required");
- return IsAligned(val, GetPageSize());
- }
- } // namespace base
- #endif // BASE_MEMORY_ALIGNED_MEMORY_H_
|