blob: b28572faac1f707fc15be7f508a4ad131c9cc7c7 (
plain)
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
|
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
#ifndef CEPH_COMMON_ALLOCATOR_H
#define CEPH_COMMON_ALLOCATOR_H
#include "acconfig.h"
#ifdef LIBTCMALLOC_MISSING_ALIGNED_ALLOC
#include <malloc.h>
#include <new>
#endif
#include <memory>
namespace ceph {
#ifdef LIBTCMALLOC_MISSING_ALIGNED_ALLOC
// If libtcmalloc is missing 'aligned_alloc', provide a new allocator class that
// uses memalign which is what newer versions of tcmalloc do internally. C++17
// will automatically use 'operator new(size_t, align_val_t)' for aligned
// structures, which will invoke the missing 'aligned_alloc' tcmalloc function.
// This method was added to tcmalloc (gperftools) in commit d406f228 after
// the 2.6.1 release was tagged.
template <typename T>
struct allocator : public std::allocator<T> {
using pointer = typename std::allocator<T>::pointer;
using size_type = typename std::allocator<T>::size_type;
template<class U>
struct rebind {
typedef allocator<U> other;
};
allocator() noexcept {
}
allocator(const allocator& other) noexcept : std::allocator<T>(other) {
}
template <class U>
allocator(const allocator<U>& other) noexcept : std::allocator<T>(other) {
}
pointer allocate(size_type n, const void* hint = nullptr) {
if (n > this->max_size()) {
throw std::bad_alloc();
}
if (alignof(T) > __STDCPP_DEFAULT_NEW_ALIGNMENT__) {
return static_cast<T*>(memalign(alignof(T), n * sizeof(T)));
}
return std::allocator<T>::allocate(n, hint);
}
};
#else // LIBTCMALLOC_MISSING_ALIGNED_ALLOC
// re-use the full std::allocator implementation if tcmalloc is functional
template <typename T>
using allocator = std::allocator<T>;
#endif // LIBTCMALLOC_MISSING_ALIGNED_ALLOC
} // namespace ceph
#endif // CEPH_COMMON_ALLOCATOR_H
|