nlib
NMalloc.h
[詳解]
1 
2 /*---------------------------------------------------------------------------*
3 
4  Project: CrossRoad
5  Copyright (C)2012-2016 Nintendo. All rights reserved.
6 
7  These coded instructions, statements, and computer programs contain
8  proprietary information of Nintendo of America Inc. and/or Nintendo
9  Company Ltd., and are protected by Federal copyright law. They may
10  not be disclosed to third parties or copied or duplicated in any form,
11  in whole or in part, without the prior written consent of Nintendo.
12 
13  *---------------------------------------------------------------------------*/
14 
15 #pragma once
16 #ifndef INCLUDE_NN_NLIB_HEAP_NMALLOC_H_
17 #define INCLUDE_NN_NLIB_HEAP_NMALLOC_H_
18 
19 #include <errno.h>
20 #include <stddef.h>
21 #include <stdlib.h> // for malloc/free
22 
23 #ifdef __cplusplus
24 #include <new>
25 #include "nn/nlib/Config.h"
26 #else
27 #include "nn/nlib/Platform.h"
28 #endif
29 
30 #if defined(_MSC_VER) && defined(nx_heap_EXPORTS)
31 #undef NLIB_VIS_PUBLIC
32 #define NLIB_VIS_PUBLIC NLIB_WINEXPORT
33 #endif
34 
35 #ifndef INCLUDE_NN_NLIB_PLATFORM_H_
36 // some compilers complain about double declaration
37 typedef int errno_t;
38 #endif
39 
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43 
44 typedef struct NLIB_VIS_PUBLIC {
45  size_t alloc_count;
46  size_t alloc_size;
47  size_t hash;
48 } HeapHash;
49 
50 typedef struct NLIB_VIS_PUBLIC {
51  void* addr;
52  size_t size;
53  unsigned int heap_option;
55 
56 #define NMALLOC_HEAPOPTION_ENABLE_ENV (0x00000001)
57 #define NMALLOC_HEAPOPTION_CACHE_DISABLE (0x00000004)
58 
59 #ifdef _MSC_VER
60 void nmalloc_get_settings(NMallocSettings* settings); // weak function
61 NLIB_VIS_PUBLIC void nmalloc_get_settings_default(NMallocSettings* settings);
62 #ifndef _WIN64
63 #pragma comment(linker, "/alternatename:_nmalloc_get_settings=_nmalloc_get_settings_default")
64 #else
65 #pragma comment(linker, "/alternatename:nmalloc_get_settings=nmalloc_get_settings_default")
66 #endif
67 #else
68 NLIB_VIS_PUBLIC void nmalloc_get_settings(NMallocSettings* settings); // weak function
69 #endif
70 
71 typedef enum {
78 
79 typedef enum {
80  NMALLOC_QUERY_DUMP = 0,
81  NMALLOC_QUERY_PAGE_SIZE,
82  NMALLOC_QUERY_ALLOCATED_SIZE,
83  NMALLOC_QUERY_FREE_SIZE,
84  NMALLOC_QUERY_SYSTEM_SIZE,
85  NMALLOC_QUERY_MAX_ALLOCATABLE_SIZE,
86  NMALLOC_QUERY_IS_CLEAN,
87  NMALLOC_QUERY_HEAP_HASH,
88  NMALLOC_QUERY_UNIFY_FREELIST,
89  NMALLOC_QUERY_SET_COLOR,
90  NMALLOC_QUERY_GET_COLOR,
91  NMALLOC_QUERY_SET_NAME,
92  NMALLOC_QUERY_GET_NAME,
93  NMALLOC_QUERY_CACHE_MIN_,
94  NMALLOC_QUERY_CHECK_CACHE,
95  NMALLOC_QUERY_CLEAR_CACHE,
96  NMALLOC_QUERY_FINALIZE_CACHE
97 } NMallocQuery;
98 
99 typedef int (*nmalloc_heapwalk_callback)(void* allocated_ptr, size_t size, void* user_ptr);
100 
101 NLIB_VIS_PUBLIC errno_t nmalloc_query(int query, ...);
102 NLIB_VIS_PUBLIC NLIB_CHECK_RESULT void* nrealloc(void* ptr, size_t size)
103 NLIB_ATTRIBUTE_MALLOC NLIB_ATTRIBUTE_ALLOC_SIZE1(2) NLIB_ATTRIBUTE_ASSUME_ALIGNED(8);
104 NLIB_VIS_PUBLIC NLIB_CHECK_RESULT void* nmalloc(size_t size)
105 NLIB_ATTRIBUTE_MALLOC NLIB_ATTRIBUTE_ALLOC_SIZE1(1) NLIB_ATTRIBUTE_ASSUME_ALIGNED(8);
106 NLIB_VIS_PUBLIC NLIB_CHECK_RESULT void* ncalloc(size_t nmemb, size_t size)
107 NLIB_ATTRIBUTE_MALLOC NLIB_ATTRIBUTE_ALLOC_SIZE2(1, 2) NLIB_ATTRIBUTE_ASSUME_ALIGNED(8);
108 NLIB_VIS_PUBLIC NLIB_CHECK_RESULT void* nmalloc_aligned(size_t size, size_t algn)
109 NLIB_ATTRIBUTE_MALLOC NLIB_ATTRIBUTE_ALLOC_SIZE1(1) NLIB_ATTRIBUTE_ALLOC_ALIGN(2)
110 NLIB_ATTRIBUTE_ASSUME_ALIGNED(8);
111 NLIB_VIS_PUBLIC size_t nmalloc_size(const void* ptr) NLIB_NONNULL;
112 NLIB_VIS_PUBLIC void nfree(void* p);
113 NLIB_VIS_PUBLIC void nfree_size(void* p, size_t size);
114 
116 
117 #ifdef __cplusplus
118 }
119 #endif
120 
121 #ifdef __cplusplus
122 
123 inline bool operator==(const HeapHash& rhs, const HeapHash& lhs) {
124  return rhs.alloc_count == lhs.alloc_count && rhs.alloc_size == lhs.alloc_size &&
125  rhs.hash == lhs.hash;
126 }
127 
128 inline bool operator!=(const HeapHash& rhs, const HeapHash& lhs) {
129  return rhs.alloc_count != lhs.alloc_count || rhs.alloc_size != lhs.alloc_size ||
130  rhs.hash != lhs.hash;
131 }
132 
133 NLIB_NAMESPACE_BEGIN
134 namespace heap {
135 
136 template <typename T>
137 struct NMallocStlAllocator {
138  typedef size_t size_type;
139  typedef T value_type;
140  typedef T* pointer;
141  typedef const T* const_pointer;
142  typedef T& reference;
143  typedef const T& const_reference;
144  typedef ptrdiff_t difference_type;
145  template <typename U>
146  struct rebind {
147  typedef NMallocStlAllocator<U> other;
148  };
149  NMallocStlAllocator() {}
150  explicit NMallocStlAllocator(const NMallocStlAllocator<T>&) {}
151  template <class _Other>
152  NMallocStlAllocator(const NMallocStlAllocator<_Other>&) {}
153  pointer allocate(size_type n, const void* p = 0);
154  void deallocate(pointer p, size_type n) {
155 #if 1
156  nfree_size(p, n * sizeof(T));
157 #else
158  (void)n;
159  nfree(p);
160 #endif
161  }
162  void construct(pointer p, const T& t) { new ((void*)p) T(t); } // NOLINT
163  void construct(pointer p) { new ((void*)p) T(); } // NOLINT
164 #if defined(NLIB_CXX11_RVALUE_REFERENCES) && defined(NLIB_CXX11_VARIADIC_TEMPLATES)
165  template<class X, class... ARGS>
166  void construct(X* p, ARGS&&... args) {
167  new ((void*)p) X(std::forward<ARGS>(args)...); // NOLINT
168  }
169 #endif
170  void destroy(pointer ptr) {
171  (void)ptr;
172  (*ptr).~T();
173  }
174  template<class X>
175  void destroy(X* p) {
176  NLIB_UNUSED(p); // workaround for VS2012
177  p->~X();
178  }
179  size_t max_size() const {
180  size_t cnt = (size_t)-1 / sizeof(T);
181  return 0 < cnt ? cnt : 1;
182  }
183  pointer address(reference value) const { return &value; }
184  const_pointer address(const_reference value) const { return &value; }
185 };
186 
187 template <typename T>
188 typename NMallocStlAllocator<T>::pointer NMallocStlAllocator<T>::allocate(size_type n,
189  const void* p) {
190  (void)p;
191  void* pp = nmalloc(n * sizeof(T));
192  return reinterpret_cast<T*>(pp);
193 }
194 
195 template <class T1, class T2>
196 inline bool operator==(const NMallocStlAllocator<T1>&, const NMallocStlAllocator<T2>&) {
197  return true;
198 }
199 
200 template <class T1, class T2>
201 inline bool operator!=(const NMallocStlAllocator<T1>&, const NMallocStlAllocator<T2>&) {
202  return false;
203 }
204 
205 } // namespace heap
206 NLIB_NAMESPACE_END
207 
208 #endif
209 
210 #ifdef __cplusplus
211 #define NLIB_REPLACE_MALLOC \
212 extern "C" { \
213 void* nlib_malloc(size_t n) { \
214  return nmalloc(n); \
215  } \
216 void nlib_free(void* p) { \
217  nfree(p); \
218  } \
219 void* nlib_calloc(size_t nmemb, size_t size) { \
220  return ncalloc(nmemb, size); \
221  } \
222 void* nlib_realloc(void* ptr, size_t size) { \
223  return nrealloc(ptr, size); \
224  } \
225 void* nlib_memalign(size_t alignment, size_t size) { \
226  return nmalloc_aligned(size, alignment); \
227  } \
228 void nlib_free_size(void* ptr, size_t size) { \
229  nfree_size(ptr, size); \
230  } \
231 }
232 
233 #ifndef NN_PLATFORM_CTR
234 #define NLIB_REPLACE_MALLOC_NEW \
235  NLIB_REPLACE_MALLOC \
236 void* operator new(size_t size) { \
237  return nlib_malloc(size); \
238  } \
239 void operator delete(void* ptr) NLIB_NOEXCEPT { \
240  nlib_free(ptr); \
241  } \
242 void* operator new(size_t size, const std::nothrow_t&) NLIB_NOEXCEPT { \
243  return nlib_malloc(size); \
244  } \
245 void operator delete(void* ptr, const std::nothrow_t&) NLIB_NOEXCEPT { \
246  nlib_free(ptr); \
247  } \
248 void* operator new[](size_t size) { return nlib_malloc(size); } \
249 void operator delete[](void* ptr) NLIB_NOEXCEPT { nlib_free(ptr); } \
250 void* operator new[](size_t size, const std::nothrow_t&) NLIB_NOEXCEPT \
251 { return nlib_malloc(size); } \
252 void operator delete [](void* ptr, const std::nothrow_t&) NLIB_NOEXCEPT { nlib_free(ptr); } \
253 void operator delete(void* ptr, size_t size) NLIB_NOEXCEPT { \
254  nlib_free_size(ptr, size); \
255  } \
256 void operator delete(void* ptr, size_t size, const std::nothrow_t&) NLIB_NOEXCEPT { \
257  nlib_free_size(ptr, size); \
258  } \
259 void operator delete[](void* ptr, size_t size)NLIB_NOEXCEPT { nlib_free_size(ptr, size); } \
260 void operator delete[](void* ptr, size_t size, const std::nothrow_t&) NLIB_NOEXCEPT { \
261  nlib_free_size(ptr, size); \
262 }
263 #else
264 #define NLIB_REPLACE_MALLOC_NEW \
265  NLIB_REPLACE_MALLOC \
266 void* operator new(size_t size) throw(std::bad_alloc) { \
267  return nlib_malloc(size); \
268  } \
269 void operator delete(void* ptr) throw() { \
270  nlib_free(ptr); \
271  } \
272 void* operator new(size_t size, const std::nothrow_t&) throw() { \
273  return nlib_malloc(size); \
274  } \
275 void* operator new[](size_t size) throw(std::bad_alloc) { \
276  return nlib_malloc(size); \
277  } \
278 void operator delete[](void* ptr) throw() { \
279  nlib_free(ptr); \
280  } \
281 void* operator new[](size_t size, const std::nothrow_t&) throw() { \
282  return nlib_malloc(size); \
283  }
284 #endif
285 #else
286 #define NLIB_REPLACE_MALLOC \
287 void* nlib_malloc(size_t n) { \
288  return nmalloc(n); \
289  } \
290 void nlib_free(void* p) { \
291  nfree(p); \
292  } \
293 void* nlib_calloc(size_t nmemb, size_t size) { \
294  return ncalloc(nmemb, size); \
295  } \
296 void* nlib_realloc(void* ptr, size_t size) { \
297  return nrealloc(ptr, size); \
298  } \
299 void* nlib_memalign(size_t alignment, size_t size) { \
300  return nmalloc_aligned(size, alignment); \
301  } \
302 void nlib_free_size(void* ptr, size_t size) { \
303  nfree_size(ptr, size); \
304  }
305 #define NLIB_REPLACE_MALLOC_NEW NLIB_REPLACE_MALLOC
306 #endif
307 
308 #if defined(_MSC_VER) && defined(nx_heap_EXPORTS)
309 #undef NLIB_VIS_PUBLIC
310 #define NLIB_VIS_PUBLIC NLIB_WINIMPORT
311 #endif
312 
313 #endif // INCLUDE_NN_NLIB_HEAP_NMALLOC_H_
void nfree_size(void *p, size_t size)
メモリ領域を解放します。メモリのサイズ情報を利用することで高速にメモリを解放できることがあります。 ...
#define NLIB_ATTRIBUTE_MALLOC
利用可能であれば__attribute__((malloc))が定義されます。
int(* nmalloc_heapwalk_callback)(void *allocated_ptr, size_t size, void *user_ptr)
nmalloc_walk_allocated_ptrs()から呼び出されるユーザー定義のコールバック関数です。 ...
Definition: NMalloc.h:99
NLIB_CHECK_RESULT void * nrealloc(void *ptr, size_t size)
メモリの割り当てを変更します。realloc()C標準関数に相当します。
情報を全て表示します。
Definition: NMalloc.h:76
#define NLIB_CHECK_RESULT
関数の呼び出し元が戻り値をチェックする必要があることを示します。
size_t nmalloc_size(const void *ptr)
ptrに実際に割り当てられたメモリ量を返します。
size_t alloc_size
ヒープ内でユーザーによってアロケートされた領域のサイズの合計です。
Definition: NMalloc.h:46
bool operator==(const HeapHash &rhs, const HeapHash &lhs)
2つのサマリを比較して等価ならば、trueを返します。
Definition: NMalloc.h:123
bool operator!=(const HeapHash &rhs, const HeapHash &lhs)
2つのサマリを比較して等価でなければ、trueを返します。
Definition: NMalloc.h:128
ヒープ全体のページの割当密度の概要を視覚的に表示します。1MBを1つのASCIIキャラクタで表現しています。 ...
Definition: NMalloc.h:75
errno_t nmalloc_query(int query,...)
ヒープに関する詳細なデータの取得や操作を行います。
基本的なAPIがCリンケージで宣言されています。
NLIB_CHECK_RESULT void * ncalloc(size_t nmemb, size_t size)
0に初期化される要素とメモリの配列を割り当てます。
void nfree(void *p)
メモリ領域を解放します。free()C標準関数に相当します。
#define NLIB_VIS_PUBLIC
関数やクラス等のシンボルをライブラリの外部に公開します。
Definition: Platform_unix.h:87
unsigned int heap_option
ヒープオプションを指定します。デフォルトは0です。
Definition: NMalloc.h:53
size_t alloc_count
ヒープ内でユーザーによってアロケートされた領域の数です。
Definition: NMalloc.h:45
ユーザーによって確保されている全てのメモリのアドレスとサイズを表示します。
Definition: NMalloc.h:74
size_t size
nmallocが利用する最大のメモリサイズを指定します。4096バイトの倍数を指定する必要があります。 ...
Definition: NMalloc.h:52
nmallocの初期設定を行うパラメータを記述します。nmalloc_get_settings()を定義して設定します。 ...
Definition: NMalloc.h:50
size_t hash
ヒープ内のユーザーによるメモリ確保の状況をハッシュ値にしたものです。
Definition: NMalloc.h:47
NLIB_CHECK_RESULT void * nmalloc(size_t size)
指定バイト分のメモリ領域を確保します。malloc()C標準関数に相当します。
基本的な情報のみを表示します。
Definition: NMalloc.h:72
開発環境別の設定が書かれるファイルです。
void * addr
nmallocが利用する領域の先頭へのポインタを指定します。
Definition: NMalloc.h:51
void nmalloc_get_settings(NMallocSettings *settings)
ユーザーがこの関数を定義することでnmallocの初期化設定をコントロールすることができます。 ...
ページ単位の利用状況を表示します。
Definition: NMalloc.h:73
errno_t nmalloc_walk_allocated_ptrs(nmalloc_heapwalk_callback func, void *user_ptr)
ヒープにアロケートされた領域1つずつに対してコールバック関数func を呼び出します。
#define NLIB_NONNULL
全ての引数にNULLを指定することができないことを示します。
NMallocDumpMode
nmalloc_query()関数でNMALLOC_QUERY_DUMPを指定した場合に第2引数に指定する値の型です。 ...
Definition: NMalloc.h:71
ユーザーが利用しているヒープ内のメモリの利用状況のサマリが記述される構造体です。
Definition: NMalloc.h:44
NLIB_CHECK_RESULT void * nmalloc_aligned(size_t size, size_t algn)
アライメントを指定してメモリ領域を確保します。
int errno_t
intのtypedefで、戻り値としてPOSIXのエラー値を返すことを示します。
Definition: NMalloc.h:37