aligned_memory.h 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef BASE_MEMORY_ALIGNED_MEMORY_H_
  5. #define BASE_MEMORY_ALIGNED_MEMORY_H_
  6. #include <stddef.h>
  7. #include <stdint.h>
  8. #include <ostream>
  9. #include "base/base_export.h"
  10. #include "base/bits.h"
  11. #include "base/check.h"
  12. #include "build/build_config.h"
  13. #if defined(COMPILER_MSVC)
  14. #include <malloc.h>
  15. #else
  16. #include <stdlib.h>
  17. #endif
  18. // A runtime sized aligned allocation can be created:
  19. //
  20. // float* my_array = static_cast<float*>(AlignedAlloc(size, alignment));
  21. //
  22. // // ... later, to release the memory:
  23. // AlignedFree(my_array);
  24. //
  25. // Or using unique_ptr:
  26. //
  27. // std::unique_ptr<float, AlignedFreeDeleter> my_array(
  28. // static_cast<float*>(AlignedAlloc(size, alignment)));
  29. namespace base {
  30. // This can be replaced with std::aligned_alloc when we have C++17.
  31. // Caveat: std::aligned_alloc requires the size parameter be an integral
  32. // multiple of alignment.
  33. BASE_EXPORT void* AlignedAlloc(size_t size, size_t alignment);
  34. inline void AlignedFree(void* ptr) {
  35. #if defined(COMPILER_MSVC)
  36. _aligned_free(ptr);
  37. #else
  38. free(ptr);
  39. #endif
  40. }
  41. // Deleter for use with unique_ptr. E.g., use as
  42. // std::unique_ptr<Foo, base::AlignedFreeDeleter> foo;
  43. struct AlignedFreeDeleter {
  44. inline void operator()(void* ptr) const {
  45. AlignedFree(ptr);
  46. }
  47. };
  48. #ifdef __has_builtin
  49. #define SUPPORTS_BUILTIN_IS_ALIGNED (__has_builtin(__builtin_is_aligned))
  50. #else
  51. #define SUPPORTS_BUILTIN_IS_ALIGNED 0
  52. #endif
  53. inline bool IsAligned(uintptr_t val, size_t alignment) {
  54. // If the compiler supports builtin alignment checks prefer them.
  55. #if SUPPORTS_BUILTIN_IS_ALIGNED
  56. return __builtin_is_aligned(val, alignment);
  57. #else
  58. DCHECK(bits::IsPowerOfTwo(alignment)) << alignment << " is not a power of 2";
  59. return (val & (alignment - 1)) == 0;
  60. #endif
  61. }
  62. #undef SUPPORTS_BUILTIN_IS_ALIGNED
  63. inline bool IsAligned(const void* val, size_t alignment) {
  64. return IsAligned(reinterpret_cast<uintptr_t>(val), alignment);
  65. }
  66. } // namespace base
  67. #endif // BASE_MEMORY_ALIGNED_MEMORY_H_