forked from Pissandshittium/pissandshittium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaligned_memory.h
91 lines (74 loc) · 2.37 KB
/
aligned_memory.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// 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_