1/*
2 * Copyright (c) 2015-2017, Intel Corporation
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * * Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of Intel Corporation nor the names of its contributors
13 * may be used to endorse or promote products derived from this software
14 * without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/**
30 * \file
31 * \brief Aligned memory alloc/free.
32 */
33
34#ifndef UTIL_ALLOC_H
35#define UTIL_ALLOC_H
36
37#include <cassert>
38#include <cstddef> // size_t
39#include <limits>
40#include <memory>
41#include <new> // std::bad_alloc
42
43namespace ue2 {
44
45/** \brief 64-byte aligned, zeroed malloc.
46 *
47 * Pointers should be freed with \ref aligned_free. If we are unable to
48 * allocate the requested number of bytes, this function will throw
49 * std::bad_alloc. */
50void *aligned_zmalloc(size_t size);
51
52/** \brief Free a pointer allocated with \ref aligned_zmalloc. */
53void aligned_free(void *ptr);
54
55/** \brief Internal use only, used by AlignedAllocator. */
56void *aligned_malloc_internal(size_t size, size_t align);
57
58/** \brief Internal use only, used by AlignedAllocator. */
59void aligned_free_internal(void *ptr);
60
61/** \brief Aligned allocator class for use with STL containers. Ensures that
62 * your objects are aligned to N bytes. */
63template <class T, std::size_t N>
64class AlignedAllocator {
65public:
66 using value_type = T;
67
68 AlignedAllocator() noexcept {}
69
70 template <class U, std::size_t N2>
71 AlignedAllocator(const AlignedAllocator<U, N2> &) noexcept {}
72
73 template <class U> struct rebind {
74 using other = AlignedAllocator<U, N>;
75 };
76
77 T *allocate(std::size_t size) const {
78 size_t alloc_size = size * sizeof(T);
79 return static_cast<T *>(aligned_malloc_internal(alloc_size, N));
80 }
81
82 void deallocate(T *x, std::size_t) const noexcept {
83 aligned_free_internal(x);
84 }
85};
86
87template <class T, class U, std::size_t N, std::size_t N2>
88bool operator==(const AlignedAllocator<T, N> &,
89 const AlignedAllocator<U, N2> &) {
90 return true;
91}
92
93template <class T, class U, std::size_t N, std::size_t N2>
94bool operator!=(const AlignedAllocator<T, N> &a,
95 const AlignedAllocator<U, N2> &b) {
96 return !(a == b);
97}
98
99} // namespace ue2
100
101#endif
102