xref: /aosp_15_r20/external/XNNPACK/src/xnnpack/aligned-allocator.h (revision 4bdc94577ba0e567308109d787f7fec7b531ce36)
1*4bdc9457SAndroid Build Coastguard Worker // Copyright (c) Facebook, Inc. and its affiliates.
2*4bdc9457SAndroid Build Coastguard Worker // All rights reserved.
3*4bdc9457SAndroid Build Coastguard Worker //
4*4bdc9457SAndroid Build Coastguard Worker // This source code is licensed under the BSD-style license found in the
5*4bdc9457SAndroid Build Coastguard Worker // LICENSE file in the root directory of this source tree.
6*4bdc9457SAndroid Build Coastguard Worker 
7*4bdc9457SAndroid Build Coastguard Worker #pragma once
8*4bdc9457SAndroid Build Coastguard Worker 
9*4bdc9457SAndroid Build Coastguard Worker #include <cstddef>
10*4bdc9457SAndroid Build Coastguard Worker #include <limits>
11*4bdc9457SAndroid Build Coastguard Worker #include <memory>
12*4bdc9457SAndroid Build Coastguard Worker #include <type_traits>
13*4bdc9457SAndroid Build Coastguard Worker #include <utility>
14*4bdc9457SAndroid Build Coastguard Worker 
15*4bdc9457SAndroid Build Coastguard Worker #include <stdlib.h>
16*4bdc9457SAndroid Build Coastguard Worker 
17*4bdc9457SAndroid Build Coastguard Worker #if defined(__ANDROID__) || defined(_WIN32) || defined(__CYGWIN__)
18*4bdc9457SAndroid Build Coastguard Worker   #include <malloc.h>
19*4bdc9457SAndroid Build Coastguard Worker #endif
20*4bdc9457SAndroid Build Coastguard Worker 
21*4bdc9457SAndroid Build Coastguard Worker 
22*4bdc9457SAndroid Build Coastguard Worker template <typename T, size_t Alignment>
23*4bdc9457SAndroid Build Coastguard Worker class AlignedAllocator;
24*4bdc9457SAndroid Build Coastguard Worker 
25*4bdc9457SAndroid Build Coastguard Worker template <size_t Alignment>
26*4bdc9457SAndroid Build Coastguard Worker class AlignedAllocator<void, Alignment> {
27*4bdc9457SAndroid Build Coastguard Worker  public:
28*4bdc9457SAndroid Build Coastguard Worker   typedef void* pointer;
29*4bdc9457SAndroid Build Coastguard Worker   typedef const void* const_pointer;
30*4bdc9457SAndroid Build Coastguard Worker   typedef void value_type;
31*4bdc9457SAndroid Build Coastguard Worker 
32*4bdc9457SAndroid Build Coastguard Worker   template <class U>
33*4bdc9457SAndroid Build Coastguard Worker   struct rebind {
34*4bdc9457SAndroid Build Coastguard Worker     typedef AlignedAllocator<U, Alignment> other;
35*4bdc9457SAndroid Build Coastguard Worker   };
36*4bdc9457SAndroid Build Coastguard Worker };
37*4bdc9457SAndroid Build Coastguard Worker 
38*4bdc9457SAndroid Build Coastguard Worker template <typename T, size_t Alignment>
39*4bdc9457SAndroid Build Coastguard Worker class AlignedAllocator {
40*4bdc9457SAndroid Build Coastguard Worker  public:
41*4bdc9457SAndroid Build Coastguard Worker   typedef T value_type;
42*4bdc9457SAndroid Build Coastguard Worker   typedef T* pointer;
43*4bdc9457SAndroid Build Coastguard Worker   typedef const T* const_pointer;
44*4bdc9457SAndroid Build Coastguard Worker   typedef T& reference;
45*4bdc9457SAndroid Build Coastguard Worker   typedef const T& const_reference;
46*4bdc9457SAndroid Build Coastguard Worker   typedef size_t size_type;
47*4bdc9457SAndroid Build Coastguard Worker   typedef ptrdiff_t difference_type;
48*4bdc9457SAndroid Build Coastguard Worker 
49*4bdc9457SAndroid Build Coastguard Worker #if __cplusplus >= 201402L
50*4bdc9457SAndroid Build Coastguard Worker   typedef std::true_type propagate_on_container_move_assignment;
51*4bdc9457SAndroid Build Coastguard Worker #endif
52*4bdc9457SAndroid Build Coastguard Worker 
53*4bdc9457SAndroid Build Coastguard Worker   template <class U>
54*4bdc9457SAndroid Build Coastguard Worker   struct rebind {
55*4bdc9457SAndroid Build Coastguard Worker     typedef AlignedAllocator<U, Alignment> other;
56*4bdc9457SAndroid Build Coastguard Worker   };
57*4bdc9457SAndroid Build Coastguard Worker 
58*4bdc9457SAndroid Build Coastguard Worker  public:
AlignedAllocator()59*4bdc9457SAndroid Build Coastguard Worker   inline AlignedAllocator() noexcept {}
60*4bdc9457SAndroid Build Coastguard Worker 
61*4bdc9457SAndroid Build Coastguard Worker   template <class U>
AlignedAllocator(const AlignedAllocator<U,Alignment> & other)62*4bdc9457SAndroid Build Coastguard Worker   inline AlignedAllocator(
63*4bdc9457SAndroid Build Coastguard Worker       const AlignedAllocator<U, Alignment>& other) noexcept {}
64*4bdc9457SAndroid Build Coastguard Worker 
max_size()65*4bdc9457SAndroid Build Coastguard Worker   inline size_type max_size() const noexcept {
66*4bdc9457SAndroid Build Coastguard Worker     return (std::numeric_limits<size_type>::max() - size_type(Alignment)) /
67*4bdc9457SAndroid Build Coastguard Worker         sizeof(T);
68*4bdc9457SAndroid Build Coastguard Worker   }
69*4bdc9457SAndroid Build Coastguard Worker 
address(reference x)70*4bdc9457SAndroid Build Coastguard Worker   inline pointer address(reference x) const noexcept {
71*4bdc9457SAndroid Build Coastguard Worker     return std::addressof(x);
72*4bdc9457SAndroid Build Coastguard Worker   }
73*4bdc9457SAndroid Build Coastguard Worker 
address(const_reference x)74*4bdc9457SAndroid Build Coastguard Worker   inline const_pointer address(const_reference x) const noexcept {
75*4bdc9457SAndroid Build Coastguard Worker     return std::addressof(x);
76*4bdc9457SAndroid Build Coastguard Worker   }
77*4bdc9457SAndroid Build Coastguard Worker 
78*4bdc9457SAndroid Build Coastguard Worker   inline pointer allocate(
79*4bdc9457SAndroid Build Coastguard Worker       size_type n,
80*4bdc9457SAndroid Build Coastguard Worker       typename AlignedAllocator<void, Alignment>::const_pointer hint = 0) {
81*4bdc9457SAndroid Build Coastguard Worker #if defined(_WIN32)
82*4bdc9457SAndroid Build Coastguard Worker     void* memory = nullptr;
83*4bdc9457SAndroid Build Coastguard Worker     memory = _aligned_malloc(n * sizeof(T), Alignment);
84*4bdc9457SAndroid Build Coastguard Worker     if (memory == 0) {
85*4bdc9457SAndroid Build Coastguard Worker #if !defined(__GNUC__) && !defined(_MSC_VER) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)
86*4bdc9457SAndroid Build Coastguard Worker       throw std::bad_alloc();
87*4bdc9457SAndroid Build Coastguard Worker #endif
88*4bdc9457SAndroid Build Coastguard Worker     }
89*4bdc9457SAndroid Build Coastguard Worker #elif defined(__ANDROID__) || defined(__CYGWIN__)
90*4bdc9457SAndroid Build Coastguard Worker     void* memory = memalign(Alignment, n * sizeof(T));
91*4bdc9457SAndroid Build Coastguard Worker     if (memory == 0) {
92*4bdc9457SAndroid Build Coastguard Worker #if !defined(__GNUC__) || defined(__EXCEPTIONS)
93*4bdc9457SAndroid Build Coastguard Worker       throw std::bad_alloc();
94*4bdc9457SAndroid Build Coastguard Worker #endif
95*4bdc9457SAndroid Build Coastguard Worker     }
96*4bdc9457SAndroid Build Coastguard Worker #else
97*4bdc9457SAndroid Build Coastguard Worker     void* memory = nullptr;
98*4bdc9457SAndroid Build Coastguard Worker     if (posix_memalign(&memory, Alignment, n * sizeof(T)) != 0) {
99*4bdc9457SAndroid Build Coastguard Worker #if !defined(__GNUC__) || defined(__EXCEPTIONS)
100*4bdc9457SAndroid Build Coastguard Worker       throw std::bad_alloc();
101*4bdc9457SAndroid Build Coastguard Worker #endif
102*4bdc9457SAndroid Build Coastguard Worker     }
103*4bdc9457SAndroid Build Coastguard Worker #endif
104*4bdc9457SAndroid Build Coastguard Worker     return static_cast<pointer>(memory);
105*4bdc9457SAndroid Build Coastguard Worker   }
106*4bdc9457SAndroid Build Coastguard Worker 
deallocate(pointer p,size_type n)107*4bdc9457SAndroid Build Coastguard Worker   inline void deallocate(pointer p, size_type n) noexcept {
108*4bdc9457SAndroid Build Coastguard Worker #if defined(_WIN32)
109*4bdc9457SAndroid Build Coastguard Worker     _aligned_free(static_cast<void*>(p));
110*4bdc9457SAndroid Build Coastguard Worker #else
111*4bdc9457SAndroid Build Coastguard Worker     free(static_cast<void*>(p));
112*4bdc9457SAndroid Build Coastguard Worker #endif
113*4bdc9457SAndroid Build Coastguard Worker   }
114*4bdc9457SAndroid Build Coastguard Worker 
115*4bdc9457SAndroid Build Coastguard Worker   template <class U, class... Args>
construct(U * p,Args &&...args)116*4bdc9457SAndroid Build Coastguard Worker   inline void construct(U* p, Args&&... args) {
117*4bdc9457SAndroid Build Coastguard Worker     ::new (static_cast<void*>(p)) U(std::forward<Args>(args)...);
118*4bdc9457SAndroid Build Coastguard Worker   }
119*4bdc9457SAndroid Build Coastguard Worker 
120*4bdc9457SAndroid Build Coastguard Worker   template <class U>
destroy(U * p)121*4bdc9457SAndroid Build Coastguard Worker   inline void destroy(U* p) {
122*4bdc9457SAndroid Build Coastguard Worker     p->~U();
123*4bdc9457SAndroid Build Coastguard Worker   }
124*4bdc9457SAndroid Build Coastguard Worker };
125