summaryrefslogtreecommitdiffstats
path: root/src/common/allocator.h
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