nlib
NMalloc.h
Go to the documentation of this file.
1 
2 #pragma once
3 #ifndef INCLUDE_NN_NLIB_HEAP_NMALLOC_H_
4 #define INCLUDE_NN_NLIB_HEAP_NMALLOC_H_
5 
6 #include <errno.h>
7 #include <stddef.h>
8 #include <stdlib.h> // for malloc/free
9 
10 #ifdef __cplusplus
11 #include <new>
12 #include "nn/nlib/Config.h"
13 #else
14 #include "nn/nlib/Platform.h"
15 #endif
16 
17 #if defined(_MSC_VER) && defined(nx_heap_EXPORTS)
18 #undef NLIB_VIS_PUBLIC
19 #define NLIB_VIS_PUBLIC NLIB_WINEXPORT
20 #endif
21 
22 #ifndef INCLUDE_NN_NLIB_PLATFORM_H_
23 // some compilers complain about double declaration
24 typedef int errno_t;
25 #endif
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 typedef struct NLIB_VIS_PUBLIC {
32  size_t alloc_count;
33  size_t alloc_size;
34  size_t hash;
35 } HeapHash;
36 
37 typedef struct NLIB_VIS_PUBLIC {
38  void* addr;
39  size_t size;
40  unsigned int heap_option;
42 
43 #define NMALLOC_HEAPOPTION_ENABLE_ENV (0x00000001)
44 #define NMALLOC_HEAPOPTION_CACHE_DISABLE (0x00000004)
45 
46 #ifdef _MSC_VER
47 void nmalloc_get_settings(NMallocSettings* settings); // weak function
48 NLIB_VIS_PUBLIC void nmalloc_get_settings_default(NMallocSettings* settings);
49 #ifndef _WIN64
50 #pragma comment(linker, "/alternatename:_nmalloc_get_settings=_nmalloc_get_settings_default")
51 #else
52 #pragma comment(linker, "/alternatename:nmalloc_get_settings=nmalloc_get_settings_default")
53 #endif
54 #else
55 NLIB_VIS_PUBLIC void nmalloc_get_settings(NMallocSettings* settings); // weak function
56 #endif
57 
58 typedef enum {
65 
66 typedef enum {
67  NMALLOC_QUERY_DUMP = 0,
68  NMALLOC_QUERY_PAGE_SIZE,
69  NMALLOC_QUERY_ALLOCATED_SIZE,
70  NMALLOC_QUERY_FREE_SIZE,
71  NMALLOC_QUERY_SYSTEM_SIZE,
72  NMALLOC_QUERY_MAX_ALLOCATABLE_SIZE,
73  NMALLOC_QUERY_IS_CLEAN,
74  NMALLOC_QUERY_HEAP_HASH,
75  NMALLOC_QUERY_UNIFY_FREELIST,
76  NMALLOC_QUERY_SET_COLOR,
77  NMALLOC_QUERY_GET_COLOR,
78  NMALLOC_QUERY_SET_NAME,
79  NMALLOC_QUERY_GET_NAME,
80  NMALLOC_QUERY_CACHE_MIN_,
81  NMALLOC_QUERY_CHECK_CACHE,
82  NMALLOC_QUERY_CLEAR_CACHE,
83  NMALLOC_QUERY_FINALIZE_CACHE
84 } NMallocQuery;
85 
86 typedef int (*nmalloc_heapwalk_callback)(void* allocated_ptr, size_t size, void* user_ptr);
87 
88 NLIB_VIS_PUBLIC errno_t nmalloc_query(int query, ...);
89 NLIB_VIS_PUBLIC NLIB_CHECK_RESULT void* nrealloc(void* ptr, size_t size)
90 NLIB_ATTRIBUTE_MALLOC NLIB_ATTRIBUTE_ALLOC_SIZE1(2) NLIB_ATTRIBUTE_ASSUME_ALIGNED(8);
91 NLIB_VIS_PUBLIC NLIB_CHECK_RESULT void* nmalloc(size_t size)
92 NLIB_ATTRIBUTE_MALLOC NLIB_ATTRIBUTE_ALLOC_SIZE1(1) NLIB_ATTRIBUTE_ASSUME_ALIGNED(8);
93 NLIB_VIS_PUBLIC NLIB_CHECK_RESULT void* ncalloc(size_t nmemb, size_t size)
94 NLIB_ATTRIBUTE_MALLOC NLIB_ATTRIBUTE_ALLOC_SIZE2(1, 2) NLIB_ATTRIBUTE_ASSUME_ALIGNED(8);
95 NLIB_VIS_PUBLIC NLIB_CHECK_RESULT void* nmalloc_aligned(size_t size, size_t algn)
96 NLIB_ATTRIBUTE_MALLOC NLIB_ATTRIBUTE_ALLOC_SIZE1(1) NLIB_ATTRIBUTE_ALLOC_ALIGN(2)
97 NLIB_ATTRIBUTE_ASSUME_ALIGNED(8);
98 NLIB_VIS_PUBLIC size_t nmalloc_size(const void* ptr) NLIB_NONNULL;
99 NLIB_VIS_PUBLIC void nfree(void* p);
100 NLIB_VIS_PUBLIC void nfree_size(void* p, size_t size);
101 
103 
104 #ifdef __cplusplus
105 }
106 #endif
107 
108 #ifdef __cplusplus
109 
110 inline bool operator==(const HeapHash& rhs, const HeapHash& lhs) {
111  return rhs.alloc_count == lhs.alloc_count && rhs.alloc_size == lhs.alloc_size &&
112  rhs.hash == lhs.hash;
113 }
114 
115 inline bool operator!=(const HeapHash& rhs, const HeapHash& lhs) {
116  return rhs.alloc_count != lhs.alloc_count || rhs.alloc_size != lhs.alloc_size ||
117  rhs.hash != lhs.hash;
118 }
119 
120 NLIB_NAMESPACE_BEGIN
121 namespace heap {
122 
123 template <typename T>
124 struct NMallocStlAllocator {
125  typedef size_t size_type;
126  typedef T value_type;
127  typedef T* pointer;
128  typedef const T* const_pointer;
129  typedef T& reference;
130  typedef const T& const_reference;
131  typedef ptrdiff_t difference_type;
132  template <typename U>
133  struct rebind {
134  typedef NMallocStlAllocator<U> other;
135  };
136  NMallocStlAllocator() {}
137  explicit NMallocStlAllocator(const NMallocStlAllocator<T>&) {}
138  template <class _Other>
139  NMallocStlAllocator(const NMallocStlAllocator<_Other>&) {}
140  pointer allocate(size_type n, const void* p = 0);
141  void deallocate(pointer p, size_type n) {
142 #if 1
143  nfree_size(p, n * sizeof(T));
144 #else
145  (void)n;
146  nfree(p);
147 #endif
148  }
149  void construct(pointer p, const T& t) { new ((void*)p) T(t); } // NOLINT
150  void construct(pointer p) { new ((void*)p) T(); } // NOLINT
151 #if defined(NLIB_CXX11_RVALUE_REFERENCES) && defined(NLIB_CXX11_VARIADIC_TEMPLATES)
152  template<class X, class... ARGS>
153  void construct(X* p, ARGS&&... args) {
154  new ((void*)p) X(std::forward<ARGS>(args)...); // NOLINT
155  }
156 #endif
157  void destroy(pointer ptr) {
158  (void)ptr;
159  (*ptr).~T();
160  }
161  template<class X>
162  void destroy(X* p) {
163  NLIB_UNUSED(p); // workaround for VS2012
164  p->~X();
165  }
166  size_t max_size() const {
167  size_t cnt = (size_t)-1 / sizeof(T);
168  return 0 < cnt ? cnt : 1;
169  }
170  pointer address(reference value) const { return &value; }
171  const_pointer address(const_reference value) const { return &value; }
172 };
173 
174 template <typename T>
175 typename NMallocStlAllocator<T>::pointer NMallocStlAllocator<T>::allocate(size_type n,
176  const void* p) {
177  (void)p;
178  void* pp = nmalloc(n * sizeof(T));
179  return reinterpret_cast<T*>(pp);
180 }
181 
182 template <class T1, class T2>
183 inline bool operator==(const NMallocStlAllocator<T1>&, const NMallocStlAllocator<T2>&) {
184  return true;
185 }
186 
187 template <class T1, class T2>
188 inline bool operator!=(const NMallocStlAllocator<T1>&, const NMallocStlAllocator<T2>&) {
189  return false;
190 }
191 
192 } // namespace heap
193 NLIB_NAMESPACE_END
194 
195 #endif
196 
197 #ifdef __cplusplus
198 #define NLIB_REPLACE_MALLOC \
199 extern "C" { \
200 void* nlib_malloc(size_t n) { \
201  return nmalloc(n); \
202  } \
203 void nlib_free(void* p) { \
204  nfree(p); \
205  } \
206 void* nlib_calloc(size_t nmemb, size_t size) { \
207  return ncalloc(nmemb, size); \
208  } \
209 void* nlib_realloc(void* ptr, size_t size) { \
210  return nrealloc(ptr, size); \
211  } \
212 void* nlib_memalign(size_t alignment, size_t size) { \
213  return nmalloc_aligned(size, alignment); \
214  } \
215 void nlib_free_size(void* ptr, size_t size) { \
216  nfree_size(ptr, size); \
217  } \
218 }
219 
220 #ifndef NN_PLATFORM_CTR
221 #define NLIB_REPLACE_MALLOC_NEW \
222  NLIB_REPLACE_MALLOC \
223 void* operator new(size_t size) { \
224  return nlib_malloc(size); \
225  } \
226 void operator delete(void* ptr) NLIB_NOEXCEPT { \
227  nlib_free(ptr); \
228  } \
229 void* operator new(size_t size, const std::nothrow_t&) NLIB_NOEXCEPT { \
230  return nlib_malloc(size); \
231  } \
232 void operator delete(void* ptr, const std::nothrow_t&) NLIB_NOEXCEPT { \
233  nlib_free(ptr); \
234  } \
235 void* operator new[](size_t size) { return nlib_malloc(size); } \
236 void operator delete[](void* ptr) NLIB_NOEXCEPT { nlib_free(ptr); } \
237 void* operator new[](size_t size, const std::nothrow_t&) NLIB_NOEXCEPT \
238 { return nlib_malloc(size); } \
239 void operator delete [](void* ptr, const std::nothrow_t&) NLIB_NOEXCEPT { nlib_free(ptr); } \
240 void operator delete(void* ptr, size_t size) NLIB_NOEXCEPT { \
241  nlib_free_size(ptr, size); \
242  } \
243 void operator delete(void* ptr, size_t size, const std::nothrow_t&) NLIB_NOEXCEPT { \
244  nlib_free_size(ptr, size); \
245  } \
246 void operator delete[](void* ptr, size_t size)NLIB_NOEXCEPT { nlib_free_size(ptr, size); } \
247 void operator delete[](void* ptr, size_t size, const std::nothrow_t&) NLIB_NOEXCEPT { \
248  nlib_free_size(ptr, size); \
249 }
250 #else
251 #define NLIB_REPLACE_MALLOC_NEW \
252  NLIB_REPLACE_MALLOC \
253 void* operator new(size_t size) throw(std::bad_alloc) { \
254  return nlib_malloc(size); \
255  } \
256 void operator delete(void* ptr) throw() { \
257  nlib_free(ptr); \
258  } \
259 void* operator new(size_t size, const std::nothrow_t&) throw() { \
260  return nlib_malloc(size); \
261  } \
262 void* operator new[](size_t size) throw(std::bad_alloc) { \
263  return nlib_malloc(size); \
264  } \
265 void operator delete[](void* ptr) throw() { \
266  nlib_free(ptr); \
267  } \
268 void* operator new[](size_t size, const std::nothrow_t&) throw() { \
269  return nlib_malloc(size); \
270  }
271 #endif
272 #else
273 #define NLIB_REPLACE_MALLOC \
274 void* nlib_malloc(size_t n) { \
275  return nmalloc(n); \
276  } \
277 void nlib_free(void* p) { \
278  nfree(p); \
279  } \
280 void* nlib_calloc(size_t nmemb, size_t size) { \
281  return ncalloc(nmemb, size); \
282  } \
283 void* nlib_realloc(void* ptr, size_t size) { \
284  return nrealloc(ptr, size); \
285  } \
286 void* nlib_memalign(size_t alignment, size_t size) { \
287  return nmalloc_aligned(size, alignment); \
288  } \
289 void nlib_free_size(void* ptr, size_t size) { \
290  nfree_size(ptr, size); \
291  }
292 #define NLIB_REPLACE_MALLOC_NEW NLIB_REPLACE_MALLOC
293 #endif
294 
295 #if defined(_MSC_VER) && defined(nx_heap_EXPORTS)
296 #undef NLIB_VIS_PUBLIC
297 #define NLIB_VIS_PUBLIC NLIB_WINIMPORT
298 #endif
299 
300 #endif // INCLUDE_NN_NLIB_HEAP_NMALLOC_H_
void nfree_size(void *p, size_t size)
Frees a memory region. Using information about memory sizes makes it possible to free memory quickly...
#define NLIB_ATTRIBUTE_MALLOC
Defines __attribute__((malloc)) if it is available for use.
Definition: Platform_unix.h:83
int(* nmalloc_heapwalk_callback)(void *allocated_ptr, size_t size, void *user_ptr)
User-defined callback function that is called from nmalloc_walk_allocated_ptrs.
Definition: NMalloc.h:86
NLIB_CHECK_RESULT void * nrealloc(void *ptr, size_t size)
Changes the memory allocation. Corresponds to the standard C function realloc.
Displays all information.
Definition: NMalloc.h:63
#define NLIB_CHECK_RESULT
Indicates that the caller of the function must check the returned value.
Definition: Platform_unix.h:74
size_t nmalloc_size(const void *ptr)
Returns the amount of memory actually allocated at the ptr parameter.
size_t alloc_size
Total size of the regions allocated by the user application within the heap.
Definition: NMalloc.h:33
bool operator==(const HeapHash &rhs, const HeapHash &lhs)
Returns true if the two compared summaries are equal.
Definition: NMalloc.h:110
bool operator!=(const HeapHash &rhs, const HeapHash &lhs)
Returns true if the two compared summaries are not equal.
Definition: NMalloc.h:115
Visually displays the overview of the page allocation density in the entire heap. An area of 1 MB is ...
Definition: NMalloc.h:62
errno_t nmalloc_query(int query,...)
Gets and operates detailed data on the heap.
C-based declaration of the basic API.
NLIB_CHECK_RESULT void * ncalloc(size_t nmemb, size_t size)
Allocates an array of memory and elements initialized to 0.
void nfree(void *p)
Frees a memory region. Corresponds to the standard C function free.
#define NLIB_VIS_PUBLIC
Symbols for functions and classes are made available outside of the library.
Definition: Platform_unix.h:61
unsigned int heap_option
Specifies the heap options. The default is 0.
Definition: NMalloc.h:40
size_t alloc_count
Number of regions allocated by the user application within the heap.
Definition: NMalloc.h:32
Displays the addresses and sizes of all memory allocated by the user application. ...
Definition: NMalloc.h:61
size_t size
Specifies the maximum amount of memory that can be used by nmalloc. You must specify a multiple of 40...
Definition: NMalloc.h:39
Declares parameters that are initialized by nmalloc. Set by defining nmalloc_get_settings.
Definition: NMalloc.h:37
size_t hash
Hash value of the status of memory allocated by the user application within the heap.
Definition: NMalloc.h:34
NLIB_CHECK_RESULT void * nmalloc(size_t size)
Allocates a memory region of the specified size (in bytes). This corresponds to the standard C functi...
Only displays basic information.
Definition: NMalloc.h:59
A file that contains the configuration information for each development environment.
void * addr
Specifies a pointer to the beginning of the region used by nmalloc.
Definition: NMalloc.h:38
void nmalloc_get_settings(NMallocSettings *settings)
User applications can define this function to control the initialization settings of nmalloc...
Displays the usage status for each page.
Definition: NMalloc.h:60
errno_t nmalloc_walk_allocated_ptrs(nmalloc_heapwalk_callback func, void *user_ptr)
The callback function func is called for each region allocated in the heap.
#define NLIB_NONNULL
Indicates that you cannot specify NULL for all arguments.
Definition: Platform_unix.h:76
NMallocDumpMode
The type of the value that you specify for the second argument when specifying NMALLOC_QUERY_DUMP in ...
Definition: NMalloc.h:58
Structure that contains a summary of the memory usage status of the heap used by the user application...
Definition: NMalloc.h:31
NLIB_CHECK_RESULT void * nmalloc_aligned(size_t size, size_t algn)
Allocates memory with a specific alignment.
int errno_t
Indicates with an int-type typedef that a POSIX error value is returned as the return value...
Definition: NMalloc.h:24