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