nlib
NMalloc.h
[詳解]
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 #define NMALLOC_HEAPOPTION_CHECK_0 (0x00000000)
46 #define NMALLOC_HEAPOPTION_CHECK_1 (0x00000008)
47 
48 #ifdef _MSC_VER
49 void nmalloc_get_settings(NMallocSettings* settings); // weak function
50 NLIB_VIS_PUBLIC void nmalloc_get_settings_default(NMallocSettings* settings);
51 #ifndef _WIN64
52 #pragma comment(linker, "/alternatename:_nmalloc_get_settings=_nmalloc_get_settings_default")
53 #else
54 #pragma comment(linker, "/alternatename:nmalloc_get_settings=nmalloc_get_settings_default")
55 #endif
56 #else
57 NLIB_VIS_PUBLIC void nmalloc_get_settings(NMallocSettings* settings); // weak function
58 #endif
59 
60 typedef enum {
66 
67 typedef int (*nmalloc_heapwalk_callback)(void* allocated_ptr, size_t size, void* user_ptr);
68 
72 NLIB_VIS_PUBLIC void nmalloc_dump(void);
75 NLIB_VIS_PUBLIC NLIB_CHECK_RESULT void* nrealloc(void* ptr, size_t size)
76 NLIB_ATTRIBUTE_MALLOC NLIB_ATTRIBUTE_ALLOC_SIZE1(2) NLIB_ATTRIBUTE_ASSUME_ALIGNED(8);
77 NLIB_VIS_PUBLIC NLIB_CHECK_RESULT void* nmalloc(size_t size)
78 NLIB_ATTRIBUTE_MALLOC NLIB_ATTRIBUTE_ALLOC_SIZE1(1) NLIB_ATTRIBUTE_ASSUME_ALIGNED(8);
79 NLIB_VIS_PUBLIC NLIB_CHECK_RESULT void* ncalloc(size_t nmemb, size_t size)
80 NLIB_ATTRIBUTE_MALLOC NLIB_ATTRIBUTE_ALLOC_SIZE2(1, 2) NLIB_ATTRIBUTE_ASSUME_ALIGNED(8);
81 NLIB_VIS_PUBLIC NLIB_CHECK_RESULT void* nmalloc_aligned(size_t size, size_t algn)
82 NLIB_ATTRIBUTE_MALLOC NLIB_ATTRIBUTE_ALLOC_SIZE1(1) NLIB_ATTRIBUTE_ALLOC_ALIGN(2)
83 NLIB_ATTRIBUTE_ASSUME_ALIGNED(8);
84 NLIB_VIS_PUBLIC size_t nmalloc_size(const void* ptr);
85 NLIB_VIS_PUBLIC void nfree(void* p);
86 NLIB_VIS_PUBLIC void nfree_size(void* p, size_t size);
88 
90 NLIB_VIS_PUBLIC errno_t nmalloc_setmark1(void* p, uint16_t mark1);
91 NLIB_VIS_PUBLIC errno_t nmalloc_setmark2(void* p, uint16_t mark2);
92 NLIB_VIS_PUBLIC errno_t nmalloc_getmark(const void* ptr, uint16_t* mark1, uint16_t* mark2);
93 NLIB_VIS_PUBLIC void* nmalloc_getobjptr(void* raw_ptr);
94 
95 #ifdef __cplusplus
96 }
97 #endif
98 
99 #ifdef __cplusplus
100 
101 inline bool operator==(const HeapHash& rhs, const HeapHash& lhs) {
102  return rhs.alloc_count == lhs.alloc_count && rhs.alloc_size == lhs.alloc_size &&
103  rhs.hash == lhs.hash;
104 }
105 
106 inline bool operator!=(const HeapHash& rhs, const HeapHash& lhs) {
107  return rhs.alloc_count != lhs.alloc_count || rhs.alloc_size != lhs.alloc_size ||
108  rhs.hash != lhs.hash;
109 }
110 
111 NLIB_NAMESPACE_BEGIN
112 namespace heap {
113 
114 template <typename T>
115 struct NMallocStlAllocator {
116  typedef size_t size_type;
117  typedef T value_type;
118  typedef T* pointer;
119  typedef const T* const_pointer;
120  typedef T& reference;
121  typedef const T& const_reference;
122  typedef ptrdiff_t difference_type;
123  template <typename U>
124  struct rebind {
125  typedef NMallocStlAllocator<U> other;
126  };
127  NMallocStlAllocator() {}
128  explicit NMallocStlAllocator(const NMallocStlAllocator<T>&) {}
129  template <class _Other>
130  NMallocStlAllocator(const NMallocStlAllocator<_Other>&) {}
131  pointer allocate(size_type n, const void* p = 0);
132  void deallocate(pointer p, size_type n) {
133 #if 1
134  nfree_size(p, n * sizeof(T));
135 #else
136  (void)n;
137  nfree(p);
138 #endif
139  }
140  void construct(pointer p, const T& t) { new ((void*)p) T(t); } // NOLINT
141  void construct(pointer p) { new ((void*)p) T(); } // NOLINT
142 #if defined(NLIB_CXX11_RVALUE_REFERENCES) && defined(NLIB_CXX11_VARIADIC_TEMPLATES)
143  template<class X, class... ARGS>
144  void construct(X* p, ARGS&&... args) {
145  new ((void*)p) X(std::forward<ARGS>(args)...); // NOLINT
146  }
147 #endif
148  void destroy(pointer ptr) {
149  (void)ptr;
150  (*ptr).~T();
151  }
152  template<class X>
153  void destroy(X* p) {
154  NLIB_UNUSED(p); // workaround for VS2012
155  p->~X();
156  }
157  size_t max_size() const {
158  size_t cnt = (size_t)-1 / sizeof(T);
159  return 0 < cnt ? cnt : 1;
160  }
161  pointer address(reference value) const { return &value; }
162  const_pointer address(const_reference value) const { return &value; }
163 };
164 
165 template <typename T>
166 typename NMallocStlAllocator<T>::pointer NMallocStlAllocator<T>::allocate(size_type n,
167  const void* p) {
168  (void)p;
169  void* pp = nmalloc(n * sizeof(T));
170  return reinterpret_cast<T*>(pp);
171 }
172 
173 template <class T1, class T2>
174 inline bool operator==(const NMallocStlAllocator<T1>&, const NMallocStlAllocator<T2>&) {
175  return true;
176 }
177 
178 template <class T1, class T2>
179 inline bool operator!=(const NMallocStlAllocator<T1>&, const NMallocStlAllocator<T2>&) {
180  return false;
181 }
182 
183 } // namespace heap
184 NLIB_NAMESPACE_END
185 
186 #endif
187 
188 #ifdef __cplusplus
189 #define NLIB_REPLACE_MALLOC \
190 extern "C" { \
191 void* nlib_malloc(size_t n) { \
192  return nmalloc(n); \
193  } \
194 void nlib_free(void* p) { \
195  nfree(p); \
196  } \
197 void* nlib_calloc(size_t nmemb, size_t size) { \
198  return ncalloc(nmemb, size); \
199  } \
200 void* nlib_realloc(void* ptr, size_t size) { \
201  return nrealloc(ptr, size); \
202  } \
203 void* nlib_memalign(size_t alignment, size_t size) { \
204  return nmalloc_aligned(size, alignment); \
205  } \
206 void nlib_free_size(void* ptr, size_t size) { \
207  nfree_size(ptr, size); \
208  } \
209 }
210 
211 #ifndef NN_PLATFORM_CTR
212 #define NLIB_REPLACE_MALLOC_NEW \
213  NLIB_REPLACE_MALLOC \
214 void* operator new(size_t size) { \
215  return nlib_malloc(size); \
216  } \
217 void operator delete(void* ptr) NLIB_NOEXCEPT { \
218  nlib_free(ptr); \
219  } \
220 void* operator new(size_t size, const std::nothrow_t&) NLIB_NOEXCEPT { \
221  return nlib_malloc(size); \
222  } \
223 void operator delete(void* ptr, const std::nothrow_t&) NLIB_NOEXCEPT { \
224  nlib_free(ptr); \
225  } \
226 void* operator new[](size_t size) { return nlib_malloc(size); } \
227 void operator delete[](void* ptr) NLIB_NOEXCEPT { nlib_free(ptr); } \
228 void* operator new[](size_t size, const std::nothrow_t&) NLIB_NOEXCEPT \
229 { return nlib_malloc(size); } \
230 void operator delete [](void* ptr, const std::nothrow_t&) NLIB_NOEXCEPT { nlib_free(ptr); } \
231 void operator delete(void* ptr, size_t size) NLIB_NOEXCEPT { \
232  nlib_free_size(ptr, size); \
233  } \
234 void operator delete(void* ptr, size_t size, const std::nothrow_t&) NLIB_NOEXCEPT { \
235  nlib_free_size(ptr, size); \
236  } \
237 void operator delete[](void* ptr, size_t size)NLIB_NOEXCEPT { nlib_free_size(ptr, size); } \
238 void operator delete[](void* ptr, size_t size, const std::nothrow_t&) NLIB_NOEXCEPT { \
239  nlib_free_size(ptr, size); \
240 }
241 #else
242 #define NLIB_REPLACE_MALLOC_NEW \
243  NLIB_REPLACE_MALLOC \
244 void* operator new(size_t size) throw(std::bad_alloc) { \
245  return nlib_malloc(size); \
246  } \
247 void operator delete(void* ptr) throw() { \
248  nlib_free(ptr); \
249  } \
250 void* operator new(size_t size, const std::nothrow_t&) throw() { \
251  return nlib_malloc(size); \
252  } \
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 #endif
263 #else
264 #define NLIB_REPLACE_MALLOC \
265 void* nlib_malloc(size_t n) { \
266  return nmalloc(n); \
267  } \
268 void nlib_free(void* p) { \
269  nfree(p); \
270  } \
271 void* nlib_calloc(size_t nmemb, size_t size) { \
272  return ncalloc(nmemb, size); \
273  } \
274 void* nlib_realloc(void* ptr, size_t size) { \
275  return nrealloc(ptr, size); \
276  } \
277 void* nlib_memalign(size_t alignment, size_t size) { \
278  return nmalloc_aligned(size, alignment); \
279  } \
280 void nlib_free_size(void* ptr, size_t size) { \
281  nfree_size(ptr, size); \
282  }
283 #define NLIB_REPLACE_MALLOC_NEW NLIB_REPLACE_MALLOC
284 #endif
285 
286 #if defined(_MSC_VER) && defined(nx_heap_EXPORTS)
287 #undef NLIB_VIS_PUBLIC
288 #define NLIB_VIS_PUBLIC NLIB_WINIMPORT
289 #endif
290 
291 #endif // INCLUDE_NN_NLIB_HEAP_NMALLOC_H_
void nfree_size(void *p, size_t size)
メモリ領域を解放します。メモリのサイズ情報を利用することで高速にメモリを解放できることがあります。 ...
void * nmalloc_getobjptr(void *raw_ptr)
nmalloc_heapwalk_callbackに渡されたポインタをオブジェクトへのポインタに変換します。 ...
int(* nmalloc_heapwalk_callback)(void *allocated_ptr, size_t size, void *user_ptr)
nmalloc_walk_allocated_ptrs()から呼び出されるユーザー定義のコールバック関数です。 ...
Definition: NMalloc.h:67
int nmalloc_isclean(void)
ヒープの状態が初期化直後と同じかどうか確認します。
NLIB_CHECK_RESULT void * nrealloc(void *ptr, size_t size)
メモリの割り当てを変更します。realloc()C標準関数に相当します。
void nmalloc_clear_tls(void)
実行中のスレッドにキャッシュされている割り当て可能なメモリを中央ヒープに返します。 ...
void nmalloc_heaphash(HeapHash *hash)
ユーザーによるメモリ確保状況を調べてサマリを作成します。
情報を全て表示します。
Definition: NMalloc.h:64
#define NLIB_ATTRIBUTE_MALLOC
利用可能であれば__attribute__((malloc))が定義されます。
Definition: Platform_unix.h:73
errno_t nmalloc_setmark1(void *p, uint16_t mark1)
アロケートされたメモリに情報を付加します。
size_t nmalloc_size(const void *ptr)
ptrに実際に割り当てられたメモリ量を返します。
size_t alloc_size
ヒープ内でユーザーによってアロケートされた領域のサイズの合計です。
Definition: NMalloc.h:33
bool operator==(const HeapHash &rhs, const HeapHash &lhs)
2つのサマリを比較して等価ならば、trueを返します。
Definition: NMalloc.h:101
bool operator!=(const HeapHash &rhs, const HeapHash &lhs)
2つのサマリを比較して等価でなければ、trueを返します。
Definition: NMalloc.h:106
基本的なAPIがCベースで宣言されています。
NLIB_CHECK_RESULT void * ncalloc(size_t nmemb, size_t size)
0に初期化される要素とメモリの配列を割り当てます。
void nfree(void *p)
メモリ領域を解放します。free()C標準関数に相当します。
void nmalloc_dump(void)
ヒープの基本的な状況をダンプします。
unsigned int heap_option
ヒープオプションを指定します。デフォルトは0です。
Definition: NMalloc.h:40
int nlib_fd
(nlib独自の)ファイルディスクリプタで、32bit整数です。
Definition: Platform.h:1051
size_t alloc_count
ヒープ内でユーザーによってアロケートされた領域の数です。
Definition: NMalloc.h:32
ユーザーによって確保されている全てのメモリのアドレスとサイズを表示します。
Definition: NMalloc.h:63
void nmalloc_dumpex(NMallocDumpMode mode)
ヒープの状況をダンプします。
size_t size
nmallocが利用する最大のメモリサイズを指定します。4096バイトの倍数を指定する必要があります。 ...
Definition: NMalloc.h:39
void nmalloc_finalize_tls(void)
実行中のスレッド固有のメモリを全て中央ヒープに返却します。スレッドを終了させるときに呼び出す必要があ...
nmallocの初期設定を行うパラメータを記述します。nmalloc_get_settings()を定義して設定します。 ...
Definition: NMalloc.h:37
size_t hash
ヒープ内のユーザーによるメモリ確保の状況をハッシュ値にしたものです。
Definition: NMalloc.h:34
errno_t nmalloc_getmark(const void *ptr, uint16_t *mark1, uint16_t *mark2)
アロケートされたメモリに付加された情報を取得します。
NLIB_CHECK_RESULT void * nmalloc(size_t size)
指定バイト分のメモリ領域を確保します。malloc()C標準関数に相当します。
基本的な情報のみを表示します。
Definition: NMalloc.h:61
開発環境別の設定が書かれるファイルです。
void * addr
nmallocが利用する領域の先頭へのポインタを指定します。
Definition: NMalloc.h:38
void nmalloc_get_settings(NMallocSettings *settings)
ユーザーがこの関数を定義することでnmallocの初期化設定をコントロールすることができます。 ...
errno_t nmalloc_setmark2(void *p, uint16_t mark2)
アロケートされたメモリに情報を付加します。
#define NLIB_VIS_PUBLIC
関数やクラス等のシンボルをライブラリの外部に公開します。
Definition: Platform_unix.h:51
ページ単位の利用状況を表示します。
Definition: NMalloc.h:62
errno_t nmalloc_walk_allocated_ptrs(nmalloc_heapwalk_callback func, void *user_ptr)
ヒープにアロケートされた領域1つずつに対してコールバック関数func を呼び出します。
void nmalloc_dumpex2(NMallocDumpMode mode, nlib_fd fd)
ヒープの状況をダンプします。
NMallocDumpMode
nmalloc_dumpex()関数に渡す引数の型です。
Definition: NMalloc.h:60
#define NLIB_CHECK_RESULT
関数の呼び出し元が戻り値をチェックする必要があることを示します。
Definition: Platform_unix.h:64
ユーザーが利用しているヒープ内のメモリの利用状況のサマリが記述される構造体です。
Definition: NMalloc.h:31
NLIB_CHECK_RESULT void * nmalloc_aligned(size_t size, size_t algn)
アライメントを指定してメモリ領域を確保します。
int errno_t
intのtypedefで、戻り値としてPOSIXのエラー値を返すことを示します。
Definition: NMalloc.h:24