mallocn_intern.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*
  2. * This program is free software; you can redistribute it and/or
  3. * modify it under the terms of the GNU General Public License
  4. * as published by the Free Software Foundation; either version 2
  5. * of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program; if not, write to the Free Software Foundation,
  14. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  15. *
  16. * The Original Code is Copyright (C) 2013 by Blender Foundation.
  17. * All rights reserved.
  18. */
  19. /** \file
  20. * \ingroup MEM
  21. */
  22. #ifndef __MALLOCN_INTERN_H__
  23. #define __MALLOCN_INTERN_H__
  24. /* mmap exception */
  25. #if defined(WIN32)
  26. # include "mmap_win.h"
  27. #else
  28. # include <sys/mman.h>
  29. #endif
  30. #ifdef __GNUC__
  31. # define UNUSED(x) UNUSED_##x __attribute__((__unused__))
  32. #else
  33. # define UNUSED(x) UNUSED_##x
  34. #endif
  35. #undef HAVE_MALLOC_STATS
  36. #define USE_MALLOC_USABLE_SIZE /* internal, when we have malloc_usable_size() */
  37. #if defined(__linux__) || (defined(__FreeBSD_kernel__) && !defined(__FreeBSD__)) || \
  38. defined(__GLIBC__)
  39. # include <malloc.h>
  40. # define HAVE_MALLOC_STATS
  41. #elif defined(__FreeBSD__)
  42. # include <malloc_np.h>
  43. #elif defined(__APPLE__)
  44. # include <malloc/malloc.h>
  45. # define malloc_usable_size malloc_size
  46. #elif defined(WIN32)
  47. # include <malloc.h>
  48. # define malloc_usable_size _msize
  49. #elif defined(__HAIKU__)
  50. # include <malloc.h>
  51. size_t malloc_usable_size(void *ptr);
  52. #else
  53. # pragma message "We don't know how to use malloc_usable_size on your platform"
  54. # undef USE_MALLOC_USABLE_SIZE
  55. #endif
  56. /* Blame Microsoft for LLP64 and no inttypes.h, quick workaround needed: */
  57. #if defined(WIN64)
  58. # define SIZET_FORMAT "%I64u"
  59. # define SIZET_ARG(a) ((unsigned long long)(a))
  60. #else
  61. # define SIZET_FORMAT "%lu"
  62. # define SIZET_ARG(a) ((unsigned long)(a))
  63. #endif
  64. #define SIZET_ALIGN_4(len) ((len + 3) & ~(size_t)3)
  65. #ifdef __GNUC__
  66. # define LIKELY(x) __builtin_expect(!!(x), 1)
  67. # define UNLIKELY(x) __builtin_expect(!!(x), 0)
  68. #else
  69. # define LIKELY(x) (x)
  70. # define UNLIKELY(x) (x)
  71. #endif
  72. #if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__NetBSD__)
  73. // Needed for memalign on Linux and _aligned_alloc on Windows.
  74. # include <malloc.h>
  75. #else
  76. // Apple's malloc is 16-byte aligned, and does not have malloc.h, so include
  77. // stdilb instead.
  78. # include <stdlib.h>
  79. #endif
  80. /* visual studio 2012 does not define inline for C */
  81. #ifdef _MSC_VER
  82. # define MEM_INLINE static __inline
  83. #else
  84. # define MEM_INLINE static inline
  85. #endif
  86. #define IS_POW2(a) (((a) & ((a)-1)) == 0)
  87. /* Extra padding which needs to be applied on MemHead to make it aligned. */
  88. #define MEMHEAD_ALIGN_PADDING(alignment) \
  89. ((size_t)alignment - (sizeof(MemHeadAligned) % (size_t)alignment))
  90. /* Real pointer returned by the malloc or aligned_alloc. */
  91. #define MEMHEAD_REAL_PTR(memh) ((char *)memh - MEMHEAD_ALIGN_PADDING(memh->alignment))
  92. #include "mallocn_inline.h"
  93. void *aligned_malloc(size_t size, size_t alignment);
  94. void aligned_free(void *ptr);
  95. /* Prototypes for counted allocator functions */
  96. size_t MEM_lockfree_allocN_len(const void *vmemh) ATTR_WARN_UNUSED_RESULT;
  97. void MEM_lockfree_freeN(void *vmemh);
  98. void *MEM_lockfree_dupallocN(const void *vmemh) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
  99. void *MEM_lockfree_reallocN_id(void *vmemh,
  100. size_t len,
  101. const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
  102. ATTR_ALLOC_SIZE(2);
  103. void *MEM_lockfree_recallocN_id(void *vmemh,
  104. size_t len,
  105. const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
  106. ATTR_ALLOC_SIZE(2);
  107. void *MEM_lockfree_callocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
  108. ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
  109. void *MEM_lockfree_calloc_arrayN(size_t len,
  110. size_t size,
  111. const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
  112. ATTR_ALLOC_SIZE(1, 2) ATTR_NONNULL(3);
  113. void *MEM_lockfree_mallocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
  114. ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
  115. void *MEM_lockfree_malloc_arrayN(size_t len,
  116. size_t size,
  117. const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
  118. ATTR_ALLOC_SIZE(1, 2) ATTR_NONNULL(3);
  119. void *MEM_lockfree_mallocN_aligned(size_t len,
  120. size_t alignment,
  121. const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
  122. ATTR_ALLOC_SIZE(1) ATTR_NONNULL(3);
  123. void *MEM_lockfree_mapallocN(size_t len,
  124. const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
  125. ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
  126. void MEM_lockfree_printmemlist_pydict(void);
  127. void MEM_lockfree_printmemlist(void);
  128. void MEM_lockfree_callbackmemlist(void (*func)(void *));
  129. void MEM_lockfree_printmemlist_stats(void);
  130. void MEM_lockfree_set_error_callback(void (*func)(const char *));
  131. bool MEM_lockfree_consistency_check(void);
  132. void MEM_lockfree_set_lock_callback(void (*lock)(void), void (*unlock)(void));
  133. void MEM_lockfree_set_memory_debug(void);
  134. size_t MEM_lockfree_get_memory_in_use(void);
  135. size_t MEM_lockfree_get_mapped_memory_in_use(void);
  136. unsigned int MEM_lockfree_get_memory_blocks_in_use(void);
  137. void MEM_lockfree_reset_peak_memory(void);
  138. size_t MEM_lockfree_get_peak_memory(void) ATTR_WARN_UNUSED_RESULT;
  139. #ifndef NDEBUG
  140. const char *MEM_lockfree_name_ptr(void *vmemh);
  141. #endif
  142. /* Prototypes for fully guarded allocator functions */
  143. size_t MEM_guarded_allocN_len(const void *vmemh) ATTR_WARN_UNUSED_RESULT;
  144. void MEM_guarded_freeN(void *vmemh);
  145. void *MEM_guarded_dupallocN(const void *vmemh) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
  146. void *MEM_guarded_reallocN_id(void *vmemh,
  147. size_t len,
  148. const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
  149. ATTR_ALLOC_SIZE(2);
  150. void *MEM_guarded_recallocN_id(void *vmemh,
  151. size_t len,
  152. const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
  153. ATTR_ALLOC_SIZE(2);
  154. void *MEM_guarded_callocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
  155. ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
  156. void *MEM_guarded_calloc_arrayN(size_t len,
  157. size_t size,
  158. const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
  159. ATTR_ALLOC_SIZE(1, 2) ATTR_NONNULL(3);
  160. void *MEM_guarded_mallocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
  161. ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
  162. void *MEM_guarded_malloc_arrayN(size_t len,
  163. size_t size,
  164. const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
  165. ATTR_ALLOC_SIZE(1, 2) ATTR_NONNULL(3);
  166. void *MEM_guarded_mallocN_aligned(size_t len,
  167. size_t alignment,
  168. const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
  169. ATTR_ALLOC_SIZE(1) ATTR_NONNULL(3);
  170. void *MEM_guarded_mapallocN(size_t len,
  171. const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
  172. ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
  173. void MEM_guarded_printmemlist_pydict(void);
  174. void MEM_guarded_printmemlist(void);
  175. void MEM_guarded_callbackmemlist(void (*func)(void *));
  176. void MEM_guarded_printmemlist_stats(void);
  177. void MEM_guarded_set_error_callback(void (*func)(const char *));
  178. bool MEM_guarded_consistency_check(void);
  179. void MEM_guarded_set_lock_callback(void (*lock)(void), void (*unlock)(void));
  180. void MEM_guarded_set_memory_debug(void);
  181. size_t MEM_guarded_get_memory_in_use(void);
  182. size_t MEM_guarded_get_mapped_memory_in_use(void);
  183. unsigned int MEM_guarded_get_memory_blocks_in_use(void);
  184. void MEM_guarded_reset_peak_memory(void);
  185. size_t MEM_guarded_get_peak_memory(void) ATTR_WARN_UNUSED_RESULT;
  186. #ifndef NDEBUG
  187. const char *MEM_guarded_name_ptr(void *vmemh);
  188. #endif
  189. #endif /* __MALLOCN_INTERN_H__ */