MySQL  8.0.21
Source Code Documentation
malloc_allocator.h
Go to the documentation of this file.
1 /* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License, version 2.0,
5  as published by the Free Software Foundation.
6 
7  This program is also distributed with certain software (including
8  but not limited to OpenSSL) that is licensed under separate terms,
9  as designated in a particular file or component or in included license
10  documentation. The authors of MySQL hereby grant you an additional
11  permission to link the program and your derivative works with the
12  separately licensed software that they have included with MySQL.
13 
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License, version 2.0, for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22 
23 #ifndef MALLOC_ALLOCATOR_INCLUDED
24 #define MALLOC_ALLOCATOR_INCLUDED
25 
26 #include <limits>
27 #include <new>
28 #include <utility> // std::forward
29 
30 #include "my_dbug.h"
31 #include "my_sys.h"
33 #include "sql/psi_memory_key.h"
34 
35 /**
36  Malloc_allocator is a C++ STL memory allocator based on my_malloc/my_free.
37 
38  This allows for P_S instrumentation of memory allocation done by
39  internally by STL container classes.
40 
41  Example usage:
42  vector<int, Malloc_allocator<int>>
43  v((Malloc_allocator<int>(PSI_NOT_INSTRUMENTED)));
44 
45  If the type is complicated, you can just write Malloc_allocator<>(psi_key)
46  as a shorthand for Malloc_allocator<My_complicated_type>(psi_key), as all
47  Malloc_allocator instances are implicitly convertible to each other
48  and there is a default template parameter.
49 
50  @note allocate() throws std::bad_alloc() similarly to the default
51  STL memory allocator. This is necessary - STL functions which allocates
52  memory expects it. Otherwise these functions will try to use the memory,
53  leading to segfaults if memory allocation was not successful.
54 
55  @note This allocator cannot be used for std::basic_string with RHEL 6/7
56  because of this bug:
57  https://bugzilla.redhat.com/show_bug.cgi?id=1546704
58  "Define _GLIBCXX_USE_CXX11_ABI gets ignored by gcc in devtoolset-7"
59 */
60 
61 template <class T = void *>
63  // This cannot be const if we want to be able to swap.
65 
66  public:
67  typedef T value_type;
68  typedef size_t size_type;
69  typedef ptrdiff_t difference_type;
70 
71  typedef T *pointer;
72  typedef const T *const_pointer;
73 
74  typedef T &reference;
75  typedef const T &const_reference;
76 
77  pointer address(reference r) const { return &r; }
78  const_pointer address(const_reference r) const { return &r; }
79 
80  explicit Malloc_allocator(PSI_memory_key key) : m_key(key) {}
81 
82  template <class U>
83  Malloc_allocator(const Malloc_allocator<U> &other MY_ATTRIBUTE((unused)))
84  : m_key(other.psi_key()) {}
85 
86  template <class U>
88  const Malloc_allocator<U> &other MY_ATTRIBUTE((unused))) {
89  DBUG_ASSERT(m_key == other.psi_key()); // Don't swap key.
90  }
91 
92  pointer allocate(size_type n,
93  const_pointer hint MY_ATTRIBUTE((unused)) = nullptr) {
94  if (n == 0) return nullptr;
95  if (n > max_size()) throw std::bad_alloc();
96 
97  pointer p = static_cast<pointer>(
98  my_malloc(m_key, n * sizeof(T), MYF(MY_WME | ME_FATALERROR)));
99  if (p == nullptr) throw std::bad_alloc();
100  return p;
101  }
102 
103  void deallocate(pointer p, size_type) { my_free(p); }
104 
105  template <class U, class... Args>
106  void construct(U *p, Args &&... args) {
107  DBUG_ASSERT(p != nullptr);
108  try {
109  ::new ((void *)p) U(std::forward<Args>(args)...);
110  } catch (...) {
111  DBUG_ASSERT(false); // Constructor should not throw an exception.
112  }
113  }
114 
115  void destroy(pointer p) {
116  DBUG_ASSERT(p != nullptr);
117  try {
118  p->~T();
119  } catch (...) {
120  DBUG_ASSERT(false); // Destructor should not throw an exception
121  }
122  }
123 
124  size_type max_size() const {
125  return std::numeric_limits<size_t>::max() / sizeof(T);
126  }
127 
128  template <class U>
129  struct rebind {
131  };
132 
133  PSI_memory_key psi_key() const { return m_key; }
134 };
135 
136 template <class T>
138  return a1.psi_key() == a2.psi_key();
139 }
140 
141 template <class T>
143  return a1.psi_key() != a2.psi_key();
144 }
145 
146 #endif // MALLOC_ALLOCATOR_INCLUDED
#define U
Definition: ctype-tis620.cc:74
const T * const_pointer
Definition: malloc_allocator.h:72
void destroy(pointer p)
Definition: malloc_allocator.h:115
#define MY_WME
Definition: my_sys.h:117
void deallocate(pointer p, size_type)
Definition: malloc_allocator.h:103
T value_type
Definition: malloc_allocator.h:67
pointer address(reference r) const
Definition: malloc_allocator.h:77
void my_free(void *ptr)
Frees the memory pointed by the ptr.
Definition: my_memory.cc:81
unsigned int PSI_memory_key
Instrumented memory key.
Definition: psi_memory_bits.h:46
const_pointer address(const_reference r) const
Definition: malloc_allocator.h:78
Definition: malloc_allocator.h:129
#define DBUG_ASSERT(A)
Definition: my_dbug.h:199
#define MYF(v)
ptrdiff_t difference_type
Definition: malloc_allocator.h:69
Malloc_allocator & operator=(const Malloc_allocator< U > &other)
Definition: malloc_allocator.h:87
Malloc_allocator< U > other
Definition: malloc_allocator.h:130
T & reference
Definition: malloc_allocator.h:74
#define ME_FATALERROR
Definition: my_sys.h:146
pointer allocate(size_type n, const_pointer hint=nullptr)
Definition: malloc_allocator.h:92
Common header for many mysys elements.
static const char * key
Definition: suite_stubs.c:14
void construct(U *p, Args &&... args)
Definition: malloc_allocator.h:106
T * pointer
Definition: malloc_allocator.h:71
Malloc_allocator(PSI_memory_key key)
Definition: malloc_allocator.h:80
const mysql_service_registry_t * r
Definition: pfs_example_plugin_employee.cc:85
size_type max_size() const
Definition: malloc_allocator.h:124
Malloc_allocator(const Malloc_allocator< U > &other)
Definition: malloc_allocator.h:83
const T & const_reference
Definition: malloc_allocator.h:75
int n
Definition: xcom_base.cc:442
PSI_memory_key m_key
Definition: malloc_allocator.h:64
const char * p
Definition: ctype-mb.cc:1235
size_t size_type
Definition: malloc_allocator.h:68
Malloc_allocator is a C++ STL memory allocator based on my_malloc/my_free.
Definition: malloc_allocator.h:62
bool operator!=(const Malloc_allocator< T > &a1, const Malloc_allocator< T > &a2)
Definition: malloc_allocator.h:142
void * my_malloc(PSI_memory_key key, size_t size, int flags)
Below functions are used by the components.
Definition: my_memory.cc:57
PSI_memory_key psi_key() const
Definition: malloc_allocator.h:133
bool operator==(const Malloc_allocator< T > &a1, const Malloc_allocator< T > &a2)
Definition: malloc_allocator.h:137
Definition: dtoa.cc:601