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