Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/guardedalloc')
-rw-r--r--intern/guardedalloc/CMakeLists.txt38
-rw-r--r--intern/guardedalloc/MEM_guardedalloc.h351
-rw-r--r--intern/guardedalloc/cpp/mallocn.cpp23
-rw-r--r--intern/guardedalloc/intern/mallocn.c95
-rw-r--r--intern/guardedalloc/intern/mallocn_guarded_impl.c1518
-rw-r--r--intern/guardedalloc/intern/mallocn_inline.h28
-rw-r--r--intern/guardedalloc/intern/mallocn_intern.h94
-rw-r--r--intern/guardedalloc/intern/mallocn_lockfree_impl.c616
-rw-r--r--intern/guardedalloc/intern/mmap_win.c336
-rw-r--r--intern/guardedalloc/test/simpletest/memtest.c224
10 files changed, 1736 insertions, 1587 deletions
diff --git a/intern/guardedalloc/CMakeLists.txt b/intern/guardedalloc/CMakeLists.txt
index 72c3395156e..dab24af7f8d 100644
--- a/intern/guardedalloc/CMakeLists.txt
+++ b/intern/guardedalloc/CMakeLists.txt
@@ -19,8 +19,8 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- .
- ../atomic
+ .
+ ../atomic
)
set(INC_SYS
@@ -28,40 +28,40 @@ set(INC_SYS
)
set(SRC
- ./intern/mallocn.c
- ./intern/mallocn_guarded_impl.c
- ./intern/mallocn_lockfree_impl.c
+ ./intern/mallocn.c
+ ./intern/mallocn_guarded_impl.c
+ ./intern/mallocn_lockfree_impl.c
- MEM_guardedalloc.h
- ./intern/mallocn_inline.h
- ./intern/mallocn_intern.h
+ MEM_guardedalloc.h
+ ./intern/mallocn_inline.h
+ ./intern/mallocn_intern.h
- # only so the header is known by cmake
- ../atomic/atomic_ops.h
+ # only so the header is known by cmake
+ ../atomic/atomic_ops.h
)
set(LIB
)
if(WIN32 AND NOT UNIX)
- list(APPEND SRC
- intern/mmap_win.c
+ list(APPEND SRC
+ intern/mmap_win.c
- mmap_win.h
- )
+ mmap_win.h
+ )
endif()
# Jemalloc 5.0.0+ needs extra configuration.
if(WITH_MEM_JEMALLOC AND NOT ("${JEMALLOC_VERSION}" VERSION_LESS "5.0.0"))
- add_definitions(-DWITH_JEMALLOC_CONF)
+ add_definitions(-DWITH_JEMALLOC_CONF)
endif()
blender_add_lib(bf_intern_guardedalloc "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
# Override C++ alloc, optional.
if(WITH_CXX_GUARDEDALLOC)
- set(SRC
- cpp/mallocn.cpp
- )
- blender_add_lib(bf_intern_guardedalloc_cpp "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
+ set(SRC
+ cpp/mallocn.cpp
+ )
+ blender_add_lib(bf_intern_guardedalloc_cpp "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
endif()
diff --git a/intern/guardedalloc/MEM_guardedalloc.h b/intern/guardedalloc/MEM_guardedalloc.h
index 91d328afbad..4cefc27bc54 100644
--- a/intern/guardedalloc/MEM_guardedalloc.h
+++ b/intern/guardedalloc/MEM_guardedalloc.h
@@ -49,7 +49,7 @@
#ifndef __MEM_GUARDEDALLOC_H__
#define __MEM_GUARDEDALLOC_H__
-#include <stdio.h> /* needed for FILE* */
+#include <stdio.h> /* needed for FILE* */
/* needed for uintptr_t and attributes, exception, dont use BLI anywhere else in MEM_* */
#include "../../source/blender/blenlib/BLI_sys_types.h"
@@ -59,148 +59,169 @@
extern "C" {
#endif
- /** Returns the length of the allocated memory segment pointed at
- * by vmemh. If the pointer was not previously allocated by this
- * module, the result is undefined.*/
- extern size_t (*MEM_allocN_len)(const void *vmemh) ATTR_WARN_UNUSED_RESULT;
-
- /**
- * Release memory previously allocated by this module.
- */
- extern void (*MEM_freeN)(void *vmemh);
-
-#if 0 /* UNUSED */
- /**
- * Return zero if memory is not in allocated list
- */
- extern short (*MEM_testN)(void *vmemh);
+/** Returns the length of the allocated memory segment pointed at
+ * by vmemh. If the pointer was not previously allocated by this
+ * module, the result is undefined.*/
+extern size_t (*MEM_allocN_len)(const void *vmemh) ATTR_WARN_UNUSED_RESULT;
+
+/**
+ * Release memory previously allocated by this module.
+ */
+extern void (*MEM_freeN)(void *vmemh);
+
+#if 0 /* UNUSED */
+ /**
+ * Return zero if memory is not in allocated list
+ */
+ extern short (*MEM_testN)(void *vmemh);
#endif
- /**
- * Duplicates a block of memory, and returns a pointer to the
- * newly allocated block. */
- extern void *(*MEM_dupallocN)(const void *vmemh) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT;
-
- /**
- * Reallocates a block of memory, and returns pointer to the newly
- * allocated block, the old one is freed. this is not as optimized
- * as a system realloc but just makes a new allocation and copies
- * over from existing memory. */
- extern void *(*MEM_reallocN_id)(void *vmemh, size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(2);
-
- /**
- * A variant of realloc which zeros new bytes
- */
- extern void *(*MEM_recallocN_id)(void *vmemh, size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(2);
+/**
+ * Duplicates a block of memory, and returns a pointer to the
+ * newly allocated block. */
+extern void *(*MEM_dupallocN)(const void *vmemh) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT;
+
+/**
+ * Reallocates a block of memory, and returns pointer to the newly
+ * allocated block, the old one is freed. this is not as optimized
+ * as a system realloc but just makes a new allocation and copies
+ * over from existing memory. */
+extern void *(*MEM_reallocN_id)(void *vmemh,
+ size_t len,
+ const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(2);
+
+/**
+ * A variant of realloc which zeros new bytes
+ */
+extern void *(*MEM_recallocN_id)(void *vmemh,
+ size_t len,
+ const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(2);
#define MEM_reallocN(vmemh, len) MEM_reallocN_id(vmemh, len, __func__)
#define MEM_recallocN(vmemh, len) MEM_recallocN_id(vmemh, len, __func__)
- /**
- * Allocate a block of memory of size len, with tag name str. The
- * memory is cleared. The name must be static, because only a
- * pointer to it is stored ! */
- extern void *(*MEM_callocN)(size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
-
- /**
- * Allocate a block of memory of size (len * size), with tag name
- * str, aborting in case of integer overflows to prevent vulnerabilities.
- * The memory is cleared. The name must be static, because only a
- * pointer to it is stored ! */
- extern void *(*MEM_calloc_arrayN)(size_t len, size_t size, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1,2) ATTR_NONNULL(3);
-
- /**
- * Allocate a block of memory of size len, with tag name str. The
- * name must be a static, because only a pointer to it is stored !
- * */
- extern void *(*MEM_mallocN)(size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
-
- /**
- * Allocate a block of memory of size (len * size), with tag name str,
- * aborting in case of integer overflow to prevent vulnerabilities. The
- * name must be a static, because only a pointer to it is stored !
- * */
- extern void *(*MEM_malloc_arrayN)(size_t len, size_t size, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1,2) ATTR_NONNULL(3);
-
- /**
- * Allocate an aligned block of memory of size len, with tag name str. The
- * name must be a static, because only a pointer to it is stored !
- * */
- extern void *(*MEM_mallocN_aligned)(size_t len, size_t alignment, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(3);
-
- /**
- * Same as callocN, clears memory and uses mmap (disk cached) if supported.
- * Can be free'd with MEM_freeN as usual.
- * */
- extern void *(*MEM_mapallocN)(size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
-
- /** Print a list of the names and sizes of all allocated memory
- * blocks. as a python dict for easy investigation */
- extern void (*MEM_printmemlist_pydict)(void);
-
- /** Print a list of the names and sizes of all allocated memory
- * blocks. */
- extern void (*MEM_printmemlist)(void);
-
- /** calls the function on all allocated memory blocks. */
- extern void (*MEM_callbackmemlist)(void (*func)(void *));
-
- /** Print statistics about memory usage */
- extern void (*MEM_printmemlist_stats)(void);
-
- /** Set the callback function for error output. */
- extern void (*MEM_set_error_callback)(void (*func)(const char *));
-
- /**
- * Are the start/end block markers still correct ?
- *
- * @retval true for correct memory, false for corrupted memory. */
- extern bool (*MEM_consistency_check)(void);
-
- /** Set thread locking functions for safe memory allocation from multiple
- * threads, pass NULL pointers to disable thread locking again. */
- extern void (*MEM_set_lock_callback)(void (*lock)(void), void (*unlock)(void));
-
- /** Attempt to enforce OSX (or other OS's) to have malloc and stack nonzero */
- extern void (*MEM_set_memory_debug)(void);
-
- /**
- * Memory usage stats
- * - MEM_get_memory_in_use is all memory
- * - MEM_get_mapped_memory_in_use is a subset of all memory */
- extern size_t (*MEM_get_memory_in_use)(void);
- /** Get mapped memory usage. */
- extern size_t (*MEM_get_mapped_memory_in_use)(void);
- /** Get amount of memory blocks in use. */
- extern unsigned int (*MEM_get_memory_blocks_in_use)(void);
-
- /** Reset the peak memory statistic to zero. */
- extern void (*MEM_reset_peak_memory)(void);
-
- /** Get the peak memory usage in bytes, including mmap allocations. */
- extern size_t (*MEM_get_peak_memory)(void) ATTR_WARN_UNUSED_RESULT;
+/**
+ * Allocate a block of memory of size len, with tag name str. The
+ * memory is cleared. The name must be static, because only a
+ * pointer to it is stored ! */
+extern void *(*MEM_callocN)(size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
+
+/**
+ * Allocate a block of memory of size (len * size), with tag name
+ * str, aborting in case of integer overflows to prevent vulnerabilities.
+ * The memory is cleared. The name must be static, because only a
+ * pointer to it is stored ! */
+extern void *(*MEM_calloc_arrayN)(size_t len,
+ size_t size,
+ const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1, 2) ATTR_NONNULL(3);
+
+/**
+ * Allocate a block of memory of size len, with tag name str. The
+ * name must be a static, because only a pointer to it is stored !
+ * */
+extern void *(*MEM_mallocN)(size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
+
+/**
+ * Allocate a block of memory of size (len * size), with tag name str,
+ * aborting in case of integer overflow to prevent vulnerabilities. The
+ * name must be a static, because only a pointer to it is stored !
+ * */
+extern void *(*MEM_malloc_arrayN)(size_t len,
+ size_t size,
+ const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1, 2) ATTR_NONNULL(3);
+
+/**
+ * Allocate an aligned block of memory of size len, with tag name str. The
+ * name must be a static, because only a pointer to it is stored !
+ * */
+extern void *(*MEM_mallocN_aligned)(size_t len,
+ size_t alignment,
+ const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1) ATTR_NONNULL(3);
+
+/**
+ * Same as callocN, clears memory and uses mmap (disk cached) if supported.
+ * Can be free'd with MEM_freeN as usual.
+ * */
+extern void *(*MEM_mapallocN)(size_t len,
+ const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
+
+/** Print a list of the names and sizes of all allocated memory
+ * blocks. as a python dict for easy investigation */
+extern void (*MEM_printmemlist_pydict)(void);
+
+/** Print a list of the names and sizes of all allocated memory
+ * blocks. */
+extern void (*MEM_printmemlist)(void);
+
+/** calls the function on all allocated memory blocks. */
+extern void (*MEM_callbackmemlist)(void (*func)(void *));
+
+/** Print statistics about memory usage */
+extern void (*MEM_printmemlist_stats)(void);
+
+/** Set the callback function for error output. */
+extern void (*MEM_set_error_callback)(void (*func)(const char *));
+
+/**
+ * Are the start/end block markers still correct ?
+ *
+ * @retval true for correct memory, false for corrupted memory. */
+extern bool (*MEM_consistency_check)(void);
+
+/** Set thread locking functions for safe memory allocation from multiple
+ * threads, pass NULL pointers to disable thread locking again. */
+extern void (*MEM_set_lock_callback)(void (*lock)(void), void (*unlock)(void));
+
+/** Attempt to enforce OSX (or other OS's) to have malloc and stack nonzero */
+extern void (*MEM_set_memory_debug)(void);
+
+/**
+ * Memory usage stats
+ * - MEM_get_memory_in_use is all memory
+ * - MEM_get_mapped_memory_in_use is a subset of all memory */
+extern size_t (*MEM_get_memory_in_use)(void);
+/** Get mapped memory usage. */
+extern size_t (*MEM_get_mapped_memory_in_use)(void);
+/** Get amount of memory blocks in use. */
+extern unsigned int (*MEM_get_memory_blocks_in_use)(void);
+
+/** Reset the peak memory statistic to zero. */
+extern void (*MEM_reset_peak_memory)(void);
+
+/** Get the peak memory usage in bytes, including mmap allocations. */
+extern size_t (*MEM_get_peak_memory)(void) ATTR_WARN_UNUSED_RESULT;
#ifdef __GNUC__
-#define MEM_SAFE_FREE(v) do { \
- typeof(&(v)) _v = &(v); \
- if (*_v) { \
- MEM_freeN(*_v); \
- *_v = NULL; \
- } \
-} while (0)
+# define MEM_SAFE_FREE(v) \
+ do { \
+ typeof(&(v)) _v = &(v); \
+ if (*_v) { \
+ MEM_freeN(*_v); \
+ *_v = NULL; \
+ } \
+ } while (0)
#else
-#define MEM_SAFE_FREE(v) do { \
- void ** _v = (void **)&(v); \
- if (*_v) { \
- MEM_freeN(*_v); \
- *_v = NULL; \
- } \
-} while (0)
+# define MEM_SAFE_FREE(v) \
+ do { \
+ void **_v = (void **)&(v); \
+ if (*_v) { \
+ MEM_freeN(*_v); \
+ *_v = NULL; \
+ } \
+ } while (0)
#endif
/* overhead for lockfree allocator (use to avoid slop-space) */
#define MEM_SIZE_OVERHEAD sizeof(size_t)
-#define MEM_SIZE_OPTIMAL(size) ((size) - MEM_SIZE_OVERHEAD)
+#define MEM_SIZE_OPTIMAL(size) ((size)-MEM_SIZE_OVERHEAD)
#ifndef NDEBUG
extern const char *(*MEM_name_ptr)(void *vmemh);
@@ -211,39 +232,45 @@ void MEM_use_guarded_allocator(void);
#ifdef __cplusplus
/* alloc funcs for C++ only */
-#define MEM_CXX_CLASS_ALLOC_FUNCS(_id) \
-public: \
- void *operator new(size_t num_bytes) { \
- return MEM_mallocN(num_bytes, _id); \
- } \
- void operator delete(void *mem) { \
- if (mem) \
- MEM_freeN(mem); \
- } \
- void *operator new[](size_t num_bytes) { \
- return MEM_mallocN(num_bytes, _id "[]"); \
- } \
- void operator delete[](void *mem) { \
- if (mem) \
- MEM_freeN(mem); \
- } \
-
-#if defined __GNUC__
-# define OBJECT_GUARDED_NEW(type, args ...) \
- new(MEM_mallocN(sizeof(type), __func__)) type(args)
-#else
-# define OBJECT_GUARDED_NEW(type, ...) \
- new(MEM_mallocN(sizeof(type), __FUNCTION__)) type(__VA_ARGS__)
-#endif
-#define OBJECT_GUARDED_DELETE(what, type) \
- { if(what) { \
- ((type*)(what))->~type(); \
- MEM_freeN(what); \
- } } (void)0
-#endif /* __cplusplus */
+# define MEM_CXX_CLASS_ALLOC_FUNCS(_id) \
+ public: \
+ void *operator new(size_t num_bytes) \
+ { \
+ return MEM_mallocN(num_bytes, _id); \
+ } \
+ void operator delete(void *mem) \
+ { \
+ if (mem) \
+ MEM_freeN(mem); \
+ } \
+ void *operator new[](size_t num_bytes) \
+ { \
+ return MEM_mallocN(num_bytes, _id "[]"); \
+ } \
+ void operator delete[](void *mem) \
+ { \
+ if (mem) \
+ MEM_freeN(mem); \
+ }
+
+# if defined __GNUC__
+# define OBJECT_GUARDED_NEW(type, args...) new (MEM_mallocN(sizeof(type), __func__)) type(args)
+# else
+# define OBJECT_GUARDED_NEW(type, ...) \
+ new (MEM_mallocN(sizeof(type), __FUNCTION__)) type(__VA_ARGS__)
+# endif
+# define OBJECT_GUARDED_DELETE(what, type) \
+ { \
+ if (what) { \
+ ((type *)(what))->~type(); \
+ MEM_freeN(what); \
+ } \
+ } \
+ (void)0
+#endif /* __cplusplus */
#ifdef __cplusplus
}
-#endif /* __cplusplus */
+#endif /* __cplusplus */
-#endif /* __MEM_GUARDEDALLOC_H__ */
+#endif /* __MEM_GUARDEDALLOC_H__ */
diff --git a/intern/guardedalloc/cpp/mallocn.cpp b/intern/guardedalloc/cpp/mallocn.cpp
index 6582bf49545..0804e096dc6 100644
--- a/intern/guardedalloc/cpp/mallocn.cpp
+++ b/intern/guardedalloc/cpp/mallocn.cpp
@@ -18,7 +18,6 @@
* \ingroup MEM
*/
-
#include <new>
#include "../MEM_guardedalloc.h"
@@ -28,33 +27,31 @@ void *operator new[](size_t size, const char *str) throw(std::bad_alloc);
/* not default but can be used when needing to set a string */
void *operator new(size_t size, const char *str) throw(std::bad_alloc)
{
- return MEM_mallocN(size, str);
+ return MEM_mallocN(size, str);
}
void *operator new[](size_t size, const char *str) throw(std::bad_alloc)
{
- return MEM_mallocN(size, str);
+ return MEM_mallocN(size, str);
}
-
void *operator new(size_t size) throw(std::bad_alloc)
{
- return MEM_mallocN(size, "C++/anonymous");
+ return MEM_mallocN(size, "C++/anonymous");
}
void *operator new[](size_t size) throw(std::bad_alloc)
{
- return MEM_mallocN(size, "C++/anonymous[]");
+ return MEM_mallocN(size, "C++/anonymous[]");
}
-
void operator delete(void *p) throw()
{
- /* delete NULL is valid in c++ */
- if (p)
- MEM_freeN(p);
+ /* delete NULL is valid in c++ */
+ if (p)
+ MEM_freeN(p);
}
void operator delete[](void *p) throw()
{
- /* delete NULL is valid in c++ */
- if (p)
- MEM_freeN(p);
+ /* delete NULL is valid in c++ */
+ if (p)
+ MEM_freeN(p);
}
diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c
index fb778da015a..1c96856fd0d 100644
--- a/intern/guardedalloc/intern/mallocn.c
+++ b/intern/guardedalloc/intern/mallocn.c
@@ -45,7 +45,9 @@ void *(*MEM_callocN)(size_t len, const char *str) = MEM_lockfree_callocN;
void *(*MEM_calloc_arrayN)(size_t len, size_t size, const char *str) = MEM_lockfree_calloc_arrayN;
void *(*MEM_mallocN)(size_t len, const char *str) = MEM_lockfree_mallocN;
void *(*MEM_malloc_arrayN)(size_t len, size_t size, const char *str) = MEM_lockfree_malloc_arrayN;
-void *(*MEM_mallocN_aligned)(size_t len, size_t alignment, const char *str) = MEM_lockfree_mallocN_aligned;
+void *(*MEM_mallocN_aligned)(size_t len,
+ size_t alignment,
+ const char *str) = MEM_lockfree_mallocN_aligned;
void *(*MEM_mapallocN)(size_t len, const char *str) = MEM_lockfree_mapallocN;
void (*MEM_printmemlist_pydict)(void) = MEM_lockfree_printmemlist_pydict;
void (*MEM_printmemlist)(void) = MEM_lockfree_printmemlist;
@@ -53,7 +55,8 @@ void (*MEM_callbackmemlist)(void (*func)(void *)) = MEM_lockfree_callbackmemlist
void (*MEM_printmemlist_stats)(void) = MEM_lockfree_printmemlist_stats;
void (*MEM_set_error_callback)(void (*func)(const char *)) = MEM_lockfree_set_error_callback;
bool (*MEM_consistency_check)(void) = MEM_lockfree_consistency_check;
-void (*MEM_set_lock_callback)(void (*lock)(void), void (*unlock)(void)) = MEM_lockfree_set_lock_callback;
+void (*MEM_set_lock_callback)(void (*lock)(void),
+ void (*unlock)(void)) = MEM_lockfree_set_lock_callback;
void (*MEM_set_memory_debug)(void) = MEM_lockfree_set_memory_debug;
size_t (*MEM_get_memory_in_use)(void) = MEM_lockfree_get_memory_in_use;
size_t (*MEM_get_mapped_memory_in_use)(void) = MEM_lockfree_get_mapped_memory_in_use;
@@ -68,66 +71,66 @@ const char *(*MEM_name_ptr)(void *vmemh) = MEM_lockfree_name_ptr;
void *aligned_malloc(size_t size, size_t alignment)
{
#ifdef _WIN32
- return _aligned_malloc(size, alignment);
+ return _aligned_malloc(size, alignment);
#elif defined(__APPLE__)
- /* On Mac OS X, both the heap and the stack are guaranteed 16-byte aligned so
- * they work natively with SSE types with no further work.
- */
- assert(alignment == 16);
- (void)alignment;
- return malloc(size);
+ /* On Mac OS X, both the heap and the stack are guaranteed 16-byte aligned so
+ * they work natively with SSE types with no further work.
+ */
+ assert(alignment == 16);
+ (void)alignment;
+ return malloc(size);
#elif defined(__FreeBSD__) || defined(__NetBSD__)
- void *result;
+ void *result;
- if (posix_memalign(&result, alignment, size)) {
- /* non-zero means allocation error
- * either no allocation or bad alignment value
- */
- return NULL;
- }
- return result;
-#else /* This is for Linux. */
- return memalign(alignment, size);
+ if (posix_memalign(&result, alignment, size)) {
+ /* non-zero means allocation error
+ * either no allocation or bad alignment value
+ */
+ return NULL;
+ }
+ return result;
+#else /* This is for Linux. */
+ return memalign(alignment, size);
#endif
}
void aligned_free(void *ptr)
{
#ifdef _WIN32
- _aligned_free(ptr);
+ _aligned_free(ptr);
#else
- free(ptr);
+ free(ptr);
#endif
}
void MEM_use_guarded_allocator(void)
{
- MEM_allocN_len = MEM_guarded_allocN_len;
- MEM_freeN = MEM_guarded_freeN;
- MEM_dupallocN = MEM_guarded_dupallocN;
- MEM_reallocN_id = MEM_guarded_reallocN_id;
- MEM_recallocN_id = MEM_guarded_recallocN_id;
- MEM_callocN = MEM_guarded_callocN;
- MEM_calloc_arrayN = MEM_guarded_calloc_arrayN;
- MEM_mallocN = MEM_guarded_mallocN;
- MEM_malloc_arrayN = MEM_guarded_malloc_arrayN;
- MEM_mallocN_aligned = MEM_guarded_mallocN_aligned;
- MEM_mapallocN = MEM_guarded_mapallocN;
- MEM_printmemlist_pydict = MEM_guarded_printmemlist_pydict;
- MEM_printmemlist = MEM_guarded_printmemlist;
- MEM_callbackmemlist = MEM_guarded_callbackmemlist;
- MEM_printmemlist_stats = MEM_guarded_printmemlist_stats;
- MEM_set_error_callback = MEM_guarded_set_error_callback;
- MEM_consistency_check = MEM_guarded_consistency_check;
- MEM_set_lock_callback = MEM_guarded_set_lock_callback;
- MEM_set_memory_debug = MEM_guarded_set_memory_debug;
- MEM_get_memory_in_use = MEM_guarded_get_memory_in_use;
- MEM_get_mapped_memory_in_use = MEM_guarded_get_mapped_memory_in_use;
- MEM_get_memory_blocks_in_use = MEM_guarded_get_memory_blocks_in_use;
- MEM_reset_peak_memory = MEM_guarded_reset_peak_memory;
- MEM_get_peak_memory = MEM_guarded_get_peak_memory;
+ MEM_allocN_len = MEM_guarded_allocN_len;
+ MEM_freeN = MEM_guarded_freeN;
+ MEM_dupallocN = MEM_guarded_dupallocN;
+ MEM_reallocN_id = MEM_guarded_reallocN_id;
+ MEM_recallocN_id = MEM_guarded_recallocN_id;
+ MEM_callocN = MEM_guarded_callocN;
+ MEM_calloc_arrayN = MEM_guarded_calloc_arrayN;
+ MEM_mallocN = MEM_guarded_mallocN;
+ MEM_malloc_arrayN = MEM_guarded_malloc_arrayN;
+ MEM_mallocN_aligned = MEM_guarded_mallocN_aligned;
+ MEM_mapallocN = MEM_guarded_mapallocN;
+ MEM_printmemlist_pydict = MEM_guarded_printmemlist_pydict;
+ MEM_printmemlist = MEM_guarded_printmemlist;
+ MEM_callbackmemlist = MEM_guarded_callbackmemlist;
+ MEM_printmemlist_stats = MEM_guarded_printmemlist_stats;
+ MEM_set_error_callback = MEM_guarded_set_error_callback;
+ MEM_consistency_check = MEM_guarded_consistency_check;
+ MEM_set_lock_callback = MEM_guarded_set_lock_callback;
+ MEM_set_memory_debug = MEM_guarded_set_memory_debug;
+ MEM_get_memory_in_use = MEM_guarded_get_memory_in_use;
+ MEM_get_mapped_memory_in_use = MEM_guarded_get_mapped_memory_in_use;
+ MEM_get_memory_blocks_in_use = MEM_guarded_get_memory_blocks_in_use;
+ MEM_reset_peak_memory = MEM_guarded_reset_peak_memory;
+ MEM_get_peak_memory = MEM_guarded_get_peak_memory;
#ifndef NDEBUG
- MEM_name_ptr = MEM_guarded_name_ptr;
+ MEM_name_ptr = MEM_guarded_name_ptr;
#endif
}
diff --git a/intern/guardedalloc/intern/mallocn_guarded_impl.c b/intern/guardedalloc/intern/mallocn_guarded_impl.c
index 9305c11df19..b24e1c8c984 100644
--- a/intern/guardedalloc/intern/mallocn_guarded_impl.c
+++ b/intern/guardedalloc/intern/mallocn_guarded_impl.c
@@ -73,14 +73,14 @@
#endif
#ifdef DEBUG_MEMCOUNTER
- /* set this to the value that isn't being freed */
+/* set this to the value that isn't being freed */
# define DEBUG_MEMCOUNTER_ERROR_VAL 0
static int _mallocn_count = 0;
/* breakpoint here */
static void memcount_raise(const char *name)
{
- fprintf(stderr, "%s: memcount-leak, %d\n", name, _mallocn_count);
+ fprintf(stderr, "%s: memcount-leak, %d\n", name, _mallocn_count);
}
#endif
@@ -89,36 +89,36 @@ static void memcount_raise(const char *name)
/* --------------------------------------------------------------------- */
/* all memory chunks are put in linked lists */
typedef struct localLink {
- struct localLink *next, *prev;
+ struct localLink *next, *prev;
} localLink;
typedef struct localListBase {
- void *first, *last;
+ void *first, *last;
} localListBase;
/* note: keep this struct aligned (e.g., irix/gcc) - Hos */
typedef struct MemHead {
- int tag1;
- size_t len;
- struct MemHead *next, *prev;
- const char *name;
- const char *nextname;
- int tag2;
- short mmap; /* if true, memory was mmapped */
- short alignment; /* if non-zero aligned alloc was used
- * and alignment is stored here.
- */
+ int tag1;
+ size_t len;
+ struct MemHead *next, *prev;
+ const char *name;
+ const char *nextname;
+ int tag2;
+ short mmap; /* if true, memory was mmapped */
+ short alignment; /* if non-zero aligned alloc was used
+ * and alignment is stored here.
+ */
#ifdef DEBUG_MEMCOUNTER
- int _count;
+ int _count;
#endif
#ifdef DEBUG_MEMDUPLINAME
- int need_free_name, pad;
+ int need_free_name, pad;
#endif
#ifdef DEBUG_BACKTRACE
- void *backtrace[BACKTRACE_SIZE];
- int backtrace_size;
+ void *backtrace[BACKTRACE_SIZE];
+ int backtrace_size;
#endif
} MemHead;
@@ -128,12 +128,12 @@ typedef MemHead MemHeadAligned;
* we may need to extend this if blender code starts using MEM_
* functions inside OpenMP correctly with omp_set_lock() */
-#if 0 /* disable for now, only use to debug openmp code which doesn lock threads for malloc */
-#if defined(_OPENMP) && defined(DEBUG)
-# include <assert.h>
-# include <omp.h>
-# define DEBUG_OMP_MALLOC
-#endif
+#if 0 /* disable for now, only use to debug openmp code which doesn lock threads for malloc */
+# if defined(_OPENMP) && defined(DEBUG)
+# include <assert.h>
+# include <omp.h>
+# define DEBUG_OMP_MALLOC
+# endif
#endif
#ifdef DEBUG_THREADS
@@ -152,10 +152,9 @@ static pthread_t mainid;
#endif
typedef struct MemTail {
- int tag3, pad;
+ int tag3, pad;
} MemTail;
-
/* --------------------------------------------------------------------- */
/* local functions */
/* --------------------------------------------------------------------- */
@@ -181,14 +180,12 @@ static const char *check_memlist(MemHead *memh);
#define MEMTAG3 MAKE_ID('O', 'C', 'K', '!')
#define MEMFREE MAKE_ID('F', 'R', 'E', 'E')
-#define MEMNEXT(x) \
- ((MemHead *)(((char *) x) - ((char *) &(((MemHead *)0)->next))))
+#define MEMNEXT(x) ((MemHead *)(((char *)x) - ((char *)&(((MemHead *)0)->next))))
/* --------------------------------------------------------------------- */
/* vars */
/* --------------------------------------------------------------------- */
-
static unsigned int totblock = 0;
static size_t mem_in_use = 0, mmap_in_use = 0, peak_mem = 0;
@@ -201,777 +198,808 @@ static void (*thread_unlock_callback)(void) = NULL;
static bool malloc_debug_memset = false;
#ifdef malloc
-#undef malloc
+# undef malloc
#endif
#ifdef calloc
-#undef calloc
+# undef calloc
#endif
#ifdef free
-#undef free
+# undef free
#endif
-
/* --------------------------------------------------------------------- */
/* implementation */
/* --------------------------------------------------------------------- */
#ifdef __GNUC__
-__attribute__ ((format(printf, 1, 2)))
+__attribute__((format(printf, 1, 2)))
#endif
-static void print_error(const char *str, ...)
+static void
+print_error(const char *str, ...)
{
- char buf[1024];
- va_list ap;
-
- va_start(ap, str);
- vsnprintf(buf, sizeof(buf), str, ap);
- va_end(ap);
- buf[sizeof(buf) - 1] = '\0';
-
- if (error_callback)
- error_callback(buf);
- else
- fputs(buf, stderr);
+ char buf[1024];
+ va_list ap;
+
+ va_start(ap, str);
+ vsnprintf(buf, sizeof(buf), str, ap);
+ va_end(ap);
+ buf[sizeof(buf) - 1] = '\0';
+
+ if (error_callback)
+ error_callback(buf);
+ else
+ fputs(buf, stderr);
}
static void mem_lock_thread(void)
{
#ifdef DEBUG_THREADS
- static int initialized = 0;
+ static int initialized = 0;
- if (initialized == 0) {
- /* assume first allocation happens from main thread */
- mainid = pthread_self();
- initialized = 1;
- }
+ if (initialized == 0) {
+ /* assume first allocation happens from main thread */
+ mainid = pthread_self();
+ initialized = 1;
+ }
- if (!pthread_equal(pthread_self(), mainid) && thread_lock_callback == NULL) {
- assert(!"Memory function is called from non-main thread without lock");
- }
+ if (!pthread_equal(pthread_self(), mainid) && thread_lock_callback == NULL) {
+ assert(!"Memory function is called from non-main thread without lock");
+ }
#endif
#ifdef DEBUG_OMP_MALLOC
- assert(omp_in_parallel() == 0);
+ assert(omp_in_parallel() == 0);
#endif
- if (thread_lock_callback)
- thread_lock_callback();
+ if (thread_lock_callback)
+ thread_lock_callback();
}
static void mem_unlock_thread(void)
{
#ifdef DEBUG_THREADS
- if (!pthread_equal(pthread_self(), mainid) && thread_lock_callback == NULL) {
- assert(!"Thread lock was removed while allocation from thread is in progress");
- }
+ if (!pthread_equal(pthread_self(), mainid) && thread_lock_callback == NULL) {
+ assert(!"Thread lock was removed while allocation from thread is in progress");
+ }
#endif
- if (thread_unlock_callback)
- thread_unlock_callback();
+ if (thread_unlock_callback)
+ thread_unlock_callback();
}
bool MEM_guarded_consistency_check(void)
{
- const char *err_val = NULL;
- MemHead *listend;
- /* check_memlist starts from the front, and runs until it finds
- * the requested chunk. For this test, that's the last one. */
- listend = membase->last;
+ const char *err_val = NULL;
+ MemHead *listend;
+ /* check_memlist starts from the front, and runs until it finds
+ * the requested chunk. For this test, that's the last one. */
+ listend = membase->last;
- err_val = check_memlist(listend);
+ err_val = check_memlist(listend);
- return (err_val == NULL);
+ return (err_val == NULL);
}
-
void MEM_guarded_set_error_callback(void (*func)(const char *))
{
- error_callback = func;
+ error_callback = func;
}
void MEM_guarded_set_lock_callback(void (*lock)(void), void (*unlock)(void))
{
- thread_lock_callback = lock;
- thread_unlock_callback = unlock;
+ thread_lock_callback = lock;
+ thread_unlock_callback = unlock;
}
void MEM_guarded_set_memory_debug(void)
{
- malloc_debug_memset = true;
+ malloc_debug_memset = true;
}
size_t MEM_guarded_allocN_len(const void *vmemh)
{
- if (vmemh) {
- const MemHead *memh = vmemh;
-
- memh--;
- return memh->len;
- }
- else {
- return 0;
- }
+ if (vmemh) {
+ const MemHead *memh = vmemh;
+
+ memh--;
+ return memh->len;
+ }
+ else {
+ return 0;
+ }
}
void *MEM_guarded_dupallocN(const void *vmemh)
{
- void *newp = NULL;
+ void *newp = NULL;
- if (vmemh) {
- const MemHead *memh = vmemh;
- memh--;
+ if (vmemh) {
+ const MemHead *memh = vmemh;
+ memh--;
#ifndef DEBUG_MEMDUPLINAME
- if (UNLIKELY(memh->mmap))
- newp = MEM_guarded_mapallocN(memh->len, "dupli_mapalloc");
- else if (LIKELY(memh->alignment == 0))
- newp = MEM_guarded_mapallocN(memh->len, "dupli_mapalloc");
- else
- newp = MEM_guarded_mallocN_aligned(memh->len, (size_t) memh->alignment, "dupli_alloc");
-
- if (newp == NULL) return NULL;
+ if (UNLIKELY(memh->mmap))
+ newp = MEM_guarded_mapallocN(memh->len, "dupli_mapalloc");
+ else if (LIKELY(memh->alignment == 0))
+ newp = MEM_guarded_mapallocN(memh->len, "dupli_mapalloc");
+ else
+ newp = MEM_guarded_mallocN_aligned(memh->len, (size_t)memh->alignment, "dupli_alloc");
+
+ if (newp == NULL)
+ return NULL;
#else
- {
- MemHead *nmemh;
- char *name = malloc(strlen(memh->name) + 24);
-
- if (UNLIKELY(memh->mmap)) {
- sprintf(name, "%s %s", "dupli_mapalloc", memh->name);
- newp = MEM_guarded_mapallocN(memh->len, name);
- }
- else if (LIKELY(memh->alignment == 0)) {
- sprintf(name, "%s %s", "dupli_alloc", memh->name);
- newp = MEM_guarded_mallocN(memh->len, name);
- }
- else {
- sprintf(name, "%s %s", "dupli_alloc", memh->name);
- newp = MEM_guarded_mallocN_aligned(memh->len, (size_t) memh->alignment, name);
- }
-
- if (newp == NULL) return NULL;
-
- nmemh = newp;
- nmemh--;
-
- nmemh->need_free_name = 1;
- }
+ {
+ MemHead *nmemh;
+ char *name = malloc(strlen(memh->name) + 24);
+
+ if (UNLIKELY(memh->mmap)) {
+ sprintf(name, "%s %s", "dupli_mapalloc", memh->name);
+ newp = MEM_guarded_mapallocN(memh->len, name);
+ }
+ else if (LIKELY(memh->alignment == 0)) {
+ sprintf(name, "%s %s", "dupli_alloc", memh->name);
+ newp = MEM_guarded_mallocN(memh->len, name);
+ }
+ else {
+ sprintf(name, "%s %s", "dupli_alloc", memh->name);
+ newp = MEM_guarded_mallocN_aligned(memh->len, (size_t)memh->alignment, name);
+ }
+
+ if (newp == NULL)
+ return NULL;
+
+ nmemh = newp;
+ nmemh--;
+
+ nmemh->need_free_name = 1;
+ }
#endif
- memcpy(newp, vmemh, memh->len);
- }
+ memcpy(newp, vmemh, memh->len);
+ }
- return newp;
+ return newp;
}
void *MEM_guarded_reallocN_id(void *vmemh, size_t len, const char *str)
{
- void *newp = NULL;
-
- if (vmemh) {
- MemHead *memh = vmemh;
- memh--;
-
- if (LIKELY(memh->alignment == 0)) {
- newp = MEM_guarded_mallocN(len, memh->name);
- }
- else {
- newp = MEM_guarded_mallocN_aligned(len, (size_t) memh->alignment, memh->name);
- }
-
- if (newp) {
- if (len < memh->len) {
- /* shrink */
- memcpy(newp, vmemh, len);
- }
- else {
- /* grow (or remain same size) */
- memcpy(newp, vmemh, memh->len);
- }
- }
-
- MEM_guarded_freeN(vmemh);
- }
- else {
- newp = MEM_guarded_mallocN(len, str);
- }
-
- return newp;
+ void *newp = NULL;
+
+ if (vmemh) {
+ MemHead *memh = vmemh;
+ memh--;
+
+ if (LIKELY(memh->alignment == 0)) {
+ newp = MEM_guarded_mallocN(len, memh->name);
+ }
+ else {
+ newp = MEM_guarded_mallocN_aligned(len, (size_t)memh->alignment, memh->name);
+ }
+
+ if (newp) {
+ if (len < memh->len) {
+ /* shrink */
+ memcpy(newp, vmemh, len);
+ }
+ else {
+ /* grow (or remain same size) */
+ memcpy(newp, vmemh, memh->len);
+ }
+ }
+
+ MEM_guarded_freeN(vmemh);
+ }
+ else {
+ newp = MEM_guarded_mallocN(len, str);
+ }
+
+ return newp;
}
void *MEM_guarded_recallocN_id(void *vmemh, size_t len, const char *str)
{
- void *newp = NULL;
-
- if (vmemh) {
- MemHead *memh = vmemh;
- memh--;
-
- if (LIKELY(memh->alignment == 0)) {
- newp = MEM_guarded_mallocN(len, memh->name);
- }
- else {
- newp = MEM_guarded_mallocN_aligned(len, (size_t) memh->alignment, memh->name);
- }
-
- if (newp) {
- if (len < memh->len) {
- /* shrink */
- memcpy(newp, vmemh, len);
- }
- else {
- memcpy(newp, vmemh, memh->len);
-
- if (len > memh->len) {
- /* grow */
- /* zero new bytes */
- memset(((char *)newp) + memh->len, 0, len - memh->len);
- }
- }
- }
-
- MEM_guarded_freeN(vmemh);
- }
- else {
- newp = MEM_guarded_callocN(len, str);
- }
-
- return newp;
+ void *newp = NULL;
+
+ if (vmemh) {
+ MemHead *memh = vmemh;
+ memh--;
+
+ if (LIKELY(memh->alignment == 0)) {
+ newp = MEM_guarded_mallocN(len, memh->name);
+ }
+ else {
+ newp = MEM_guarded_mallocN_aligned(len, (size_t)memh->alignment, memh->name);
+ }
+
+ if (newp) {
+ if (len < memh->len) {
+ /* shrink */
+ memcpy(newp, vmemh, len);
+ }
+ else {
+ memcpy(newp, vmemh, memh->len);
+
+ if (len > memh->len) {
+ /* grow */
+ /* zero new bytes */
+ memset(((char *)newp) + memh->len, 0, len - memh->len);
+ }
+ }
+ }
+
+ MEM_guarded_freeN(vmemh);
+ }
+ else {
+ newp = MEM_guarded_callocN(len, str);
+ }
+
+ return newp;
}
#ifdef DEBUG_BACKTRACE
# if defined(__linux__) || defined(__APPLE__)
static void make_memhead_backtrace(MemHead *memh)
{
- memh->backtrace_size = backtrace(memh->backtrace, BACKTRACE_SIZE);
+ memh->backtrace_size = backtrace(memh->backtrace, BACKTRACE_SIZE);
}
static void print_memhead_backtrace(MemHead *memh)
{
- char **strings;
- int i;
+ char **strings;
+ int i;
- strings = backtrace_symbols(memh->backtrace, memh->backtrace_size);
- for (i = 0; i < memh->backtrace_size; i++) {
- print_error(" %s\n", strings[i]);
- }
+ strings = backtrace_symbols(memh->backtrace, memh->backtrace_size);
+ for (i = 0; i < memh->backtrace_size; i++) {
+ print_error(" %s\n", strings[i]);
+ }
- free(strings);
+ free(strings);
}
# else
static void make_memhead_backtrace(MemHead *memh)
{
- (void) memh; /* Ignored. */
+ (void)memh; /* Ignored. */
}
static void print_memhead_backtrace(MemHead *memh)
{
- (void) memh; /* Ignored. */
+ (void)memh; /* Ignored. */
}
-# endif /* defined(__linux__) || defined(__APPLE__) */
-#endif /* DEBUG_BACKTRACE */
+# endif /* defined(__linux__) || defined(__APPLE__) */
+#endif /* DEBUG_BACKTRACE */
static void make_memhead_header(MemHead *memh, size_t len, const char *str)
{
- MemTail *memt;
+ MemTail *memt;
- memh->tag1 = MEMTAG1;
- memh->name = str;
- memh->nextname = NULL;
- memh->len = len;
- memh->mmap = 0;
- memh->alignment = 0;
- memh->tag2 = MEMTAG2;
+ memh->tag1 = MEMTAG1;
+ memh->name = str;
+ memh->nextname = NULL;
+ memh->len = len;
+ memh->mmap = 0;
+ memh->alignment = 0;
+ memh->tag2 = MEMTAG2;
#ifdef DEBUG_MEMDUPLINAME
- memh->need_free_name = 0;
+ memh->need_free_name = 0;
#endif
#ifdef DEBUG_BACKTRACE
- make_memhead_backtrace(memh);
+ make_memhead_backtrace(memh);
#endif
- memt = (MemTail *)(((char *) memh) + sizeof(MemHead) + len);
- memt->tag3 = MEMTAG3;
+ memt = (MemTail *)(((char *)memh) + sizeof(MemHead) + len);
+ memt->tag3 = MEMTAG3;
- atomic_add_and_fetch_u(&totblock, 1);
- atomic_add_and_fetch_z(&mem_in_use, len);
+ atomic_add_and_fetch_u(&totblock, 1);
+ atomic_add_and_fetch_z(&mem_in_use, len);
- mem_lock_thread();
- addtail(membase, &memh->next);
- if (memh->next) {
- memh->nextname = MEMNEXT(memh->next)->name;
- }
- peak_mem = mem_in_use > peak_mem ? mem_in_use : peak_mem;
- mem_unlock_thread();
+ mem_lock_thread();
+ addtail(membase, &memh->next);
+ if (memh->next) {
+ memh->nextname = MEMNEXT(memh->next)->name;
+ }
+ peak_mem = mem_in_use > peak_mem ? mem_in_use : peak_mem;
+ mem_unlock_thread();
}
void *MEM_guarded_mallocN(size_t len, const char *str)
{
- MemHead *memh;
+ MemHead *memh;
- len = SIZET_ALIGN_4(len);
+ len = SIZET_ALIGN_4(len);
- memh = (MemHead *)malloc(len + sizeof(MemHead) + sizeof(MemTail));
+ memh = (MemHead *)malloc(len + sizeof(MemHead) + sizeof(MemTail));
- if (LIKELY(memh)) {
- make_memhead_header(memh, len, str);
- if (UNLIKELY(malloc_debug_memset && len))
- memset(memh + 1, 255, len);
+ if (LIKELY(memh)) {
+ make_memhead_header(memh, len, str);
+ if (UNLIKELY(malloc_debug_memset && len))
+ memset(memh + 1, 255, len);
#ifdef DEBUG_MEMCOUNTER
- if (_mallocn_count == DEBUG_MEMCOUNTER_ERROR_VAL)
- memcount_raise(__func__);
- memh->_count = _mallocn_count++;
+ if (_mallocn_count == DEBUG_MEMCOUNTER_ERROR_VAL)
+ memcount_raise(__func__);
+ memh->_count = _mallocn_count++;
#endif
- return (++memh);
- }
- print_error("Malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
- SIZET_ARG(len), str, (unsigned int) mem_in_use);
- return NULL;
+ return (++memh);
+ }
+ print_error("Malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len),
+ str,
+ (unsigned int)mem_in_use);
+ return NULL;
}
void *MEM_guarded_malloc_arrayN(size_t len, size_t size, const char *str)
{
- size_t total_size;
- if (UNLIKELY(!MEM_size_safe_multiply(len, size, &total_size))) {
- print_error("Malloc array aborted due to integer overflow: "
- "len=" SIZET_FORMAT "x" SIZET_FORMAT " in %s, total %u\n",
- SIZET_ARG(len), SIZET_ARG(size), str,
- (unsigned int) mem_in_use);
- abort();
- return NULL;
- }
-
- return MEM_guarded_mallocN(total_size, str);
+ size_t total_size;
+ if (UNLIKELY(!MEM_size_safe_multiply(len, size, &total_size))) {
+ print_error(
+ "Malloc array aborted due to integer overflow: "
+ "len=" SIZET_FORMAT "x" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len),
+ SIZET_ARG(size),
+ str,
+ (unsigned int)mem_in_use);
+ abort();
+ return NULL;
+ }
+
+ return MEM_guarded_mallocN(total_size, str);
}
void *MEM_guarded_mallocN_aligned(size_t len, size_t alignment, const char *str)
{
- MemHead *memh;
+ MemHead *memh;
- /* It's possible that MemHead's size is not properly aligned,
- * do extra padding to deal with this.
- *
- * We only support small alignments which fits into short in
- * order to save some bits in MemHead structure.
- */
- size_t extra_padding = MEMHEAD_ALIGN_PADDING(alignment);
+ /* It's possible that MemHead's size is not properly aligned,
+ * do extra padding to deal with this.
+ *
+ * We only support small alignments which fits into short in
+ * order to save some bits in MemHead structure.
+ */
+ size_t extra_padding = MEMHEAD_ALIGN_PADDING(alignment);
- /* Huge alignment values doesn't make sense and they
- * wouldn't fit into 'short' used in the MemHead.
- */
- assert(alignment < 1024);
+ /* Huge alignment values doesn't make sense and they
+ * wouldn't fit into 'short' used in the MemHead.
+ */
+ assert(alignment < 1024);
- /* We only support alignment to a power of two. */
- assert(IS_POW2(alignment));
+ /* We only support alignment to a power of two. */
+ assert(IS_POW2(alignment));
- len = SIZET_ALIGN_4(len);
+ len = SIZET_ALIGN_4(len);
- memh = (MemHead *)aligned_malloc(len + extra_padding + sizeof(MemHead) + sizeof(MemTail), alignment);
+ memh = (MemHead *)aligned_malloc(len + extra_padding + sizeof(MemHead) + sizeof(MemTail),
+ alignment);
- if (LIKELY(memh)) {
- /* We keep padding in the beginning of MemHead,
- * this way it's always possible to get MemHead
- * from the data pointer.
- */
- memh = (MemHead *)((char *)memh + extra_padding);
+ if (LIKELY(memh)) {
+ /* We keep padding in the beginning of MemHead,
+ * this way it's always possible to get MemHead
+ * from the data pointer.
+ */
+ memh = (MemHead *)((char *)memh + extra_padding);
- make_memhead_header(memh, len, str);
- memh->alignment = (short) alignment;
- if (UNLIKELY(malloc_debug_memset && len))
- memset(memh + 1, 255, len);
+ make_memhead_header(memh, len, str);
+ memh->alignment = (short)alignment;
+ if (UNLIKELY(malloc_debug_memset && len))
+ memset(memh + 1, 255, len);
#ifdef DEBUG_MEMCOUNTER
- if (_mallocn_count == DEBUG_MEMCOUNTER_ERROR_VAL)
- memcount_raise(__func__);
- memh->_count = _mallocn_count++;
+ if (_mallocn_count == DEBUG_MEMCOUNTER_ERROR_VAL)
+ memcount_raise(__func__);
+ memh->_count = _mallocn_count++;
#endif
- return (++memh);
- }
- print_error("aligned_malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
- SIZET_ARG(len), str, (unsigned int) mem_in_use);
- return NULL;
+ return (++memh);
+ }
+ print_error("aligned_malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len),
+ str,
+ (unsigned int)mem_in_use);
+ return NULL;
}
void *MEM_guarded_callocN(size_t len, const char *str)
{
- MemHead *memh;
+ MemHead *memh;
- len = SIZET_ALIGN_4(len);
+ len = SIZET_ALIGN_4(len);
- memh = (MemHead *)calloc(len + sizeof(MemHead) + sizeof(MemTail), 1);
+ memh = (MemHead *)calloc(len + sizeof(MemHead) + sizeof(MemTail), 1);
- if (memh) {
- make_memhead_header(memh, len, str);
+ if (memh) {
+ make_memhead_header(memh, len, str);
#ifdef DEBUG_MEMCOUNTER
- if (_mallocn_count == DEBUG_MEMCOUNTER_ERROR_VAL)
- memcount_raise(__func__);
- memh->_count = _mallocn_count++;
+ if (_mallocn_count == DEBUG_MEMCOUNTER_ERROR_VAL)
+ memcount_raise(__func__);
+ memh->_count = _mallocn_count++;
#endif
- return (++memh);
- }
- print_error("Calloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
- SIZET_ARG(len), str, (unsigned int) mem_in_use);
- return NULL;
+ return (++memh);
+ }
+ print_error("Calloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len),
+ str,
+ (unsigned int)mem_in_use);
+ return NULL;
}
void *MEM_guarded_calloc_arrayN(size_t len, size_t size, const char *str)
{
- size_t total_size;
- if (UNLIKELY(!MEM_size_safe_multiply(len, size, &total_size))) {
- print_error("Calloc array aborted due to integer overflow: "
- "len=" SIZET_FORMAT "x" SIZET_FORMAT " in %s, total %u\n",
- SIZET_ARG(len), SIZET_ARG(size), str,
- (unsigned int) mem_in_use);
- abort();
- return NULL;
- }
-
- return MEM_guarded_callocN(total_size, str);
+ size_t total_size;
+ if (UNLIKELY(!MEM_size_safe_multiply(len, size, &total_size))) {
+ print_error(
+ "Calloc array aborted due to integer overflow: "
+ "len=" SIZET_FORMAT "x" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len),
+ SIZET_ARG(size),
+ str,
+ (unsigned int)mem_in_use);
+ abort();
+ return NULL;
+ }
+
+ return MEM_guarded_callocN(total_size, str);
}
/* note; mmap returns zero'd memory */
void *MEM_guarded_mapallocN(size_t len, const char *str)
{
- MemHead *memh;
+ MemHead *memh;
- /* on 64 bit, simply use calloc instead, as mmap does not support
- * allocating > 4 GB on Windows. the only reason mapalloc exists
- * is to get around address space limitations in 32 bit OSes. */
- if (sizeof(void *) >= 8)
- return MEM_guarded_callocN(len, str);
+ /* on 64 bit, simply use calloc instead, as mmap does not support
+ * allocating > 4 GB on Windows. the only reason mapalloc exists
+ * is to get around address space limitations in 32 bit OSes. */
+ if (sizeof(void *) >= 8)
+ return MEM_guarded_callocN(len, str);
- len = SIZET_ALIGN_4(len);
+ len = SIZET_ALIGN_4(len);
#if defined(WIN32)
- /* our windows mmap implementation is not thread safe */
- mem_lock_thread();
+ /* our windows mmap implementation is not thread safe */
+ mem_lock_thread();
#endif
- memh = mmap(NULL, len + sizeof(MemHead) + sizeof(MemTail),
- PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
+ memh = mmap(NULL,
+ len + sizeof(MemHead) + sizeof(MemTail),
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_ANON,
+ -1,
+ 0);
#if defined(WIN32)
- mem_unlock_thread();
+ mem_unlock_thread();
#endif
- if (memh != (MemHead *)-1) {
- make_memhead_header(memh, len, str);
- memh->mmap = 1;
- atomic_add_and_fetch_z(&mmap_in_use, len);
- mem_lock_thread();
- peak_mem = mmap_in_use > peak_mem ? mmap_in_use : peak_mem;
- mem_unlock_thread();
+ if (memh != (MemHead *)-1) {
+ make_memhead_header(memh, len, str);
+ memh->mmap = 1;
+ atomic_add_and_fetch_z(&mmap_in_use, len);
+ mem_lock_thread();
+ peak_mem = mmap_in_use > peak_mem ? mmap_in_use : peak_mem;
+ mem_unlock_thread();
#ifdef DEBUG_MEMCOUNTER
- if (_mallocn_count == DEBUG_MEMCOUNTER_ERROR_VAL)
- memcount_raise(__func__);
- memh->_count = _mallocn_count++;
+ if (_mallocn_count == DEBUG_MEMCOUNTER_ERROR_VAL)
+ memcount_raise(__func__);
+ memh->_count = _mallocn_count++;
#endif
- return (++memh);
- }
- else {
- print_error("Mapalloc returns null, fallback to regular malloc: "
- "len=" SIZET_FORMAT " in %s, total %u\n",
- SIZET_ARG(len), str, (unsigned int) mmap_in_use);
- return MEM_guarded_callocN(len, str);
- }
+ return (++memh);
+ }
+ else {
+ print_error(
+ "Mapalloc returns null, fallback to regular malloc: "
+ "len=" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len),
+ str,
+ (unsigned int)mmap_in_use);
+ return MEM_guarded_callocN(len, str);
+ }
}
/* Memory statistics print */
typedef struct MemPrintBlock {
- const char *name;
- uintptr_t len;
- int items;
+ const char *name;
+ uintptr_t len;
+ int items;
} MemPrintBlock;
static int compare_name(const void *p1, const void *p2)
{
- const MemPrintBlock *pb1 = (const MemPrintBlock *)p1;
- const MemPrintBlock *pb2 = (const MemPrintBlock *)p2;
+ const MemPrintBlock *pb1 = (const MemPrintBlock *)p1;
+ const MemPrintBlock *pb2 = (const MemPrintBlock *)p2;
- return strcmp(pb1->name, pb2->name);
+ return strcmp(pb1->name, pb2->name);
}
static int compare_len(const void *p1, const void *p2)
{
- const MemPrintBlock *pb1 = (const MemPrintBlock *)p1;
- const MemPrintBlock *pb2 = (const MemPrintBlock *)p2;
-
- if (pb1->len < pb2->len)
- return 1;
- else if (pb1->len == pb2->len)
- return 0;
- else
- return -1;
+ const MemPrintBlock *pb1 = (const MemPrintBlock *)p1;
+ const MemPrintBlock *pb2 = (const MemPrintBlock *)p2;
+
+ if (pb1->len < pb2->len)
+ return 1;
+ else if (pb1->len == pb2->len)
+ return 0;
+ else
+ return -1;
}
void MEM_guarded_printmemlist_stats(void)
{
- MemHead *membl;
- MemPrintBlock *pb, *printblock;
- unsigned int totpb, a, b;
- size_t mem_in_use_slop = 0;
+ MemHead *membl;
+ MemPrintBlock *pb, *printblock;
+ unsigned int totpb, a, b;
+ size_t mem_in_use_slop = 0;
- mem_lock_thread();
+ mem_lock_thread();
- /* put memory blocks into array */
- printblock = malloc(sizeof(MemPrintBlock) * totblock);
+ /* put memory blocks into array */
+ printblock = malloc(sizeof(MemPrintBlock) * totblock);
- pb = printblock;
- totpb = 0;
+ pb = printblock;
+ totpb = 0;
- membl = membase->first;
- if (membl) membl = MEMNEXT(membl);
+ membl = membase->first;
+ if (membl)
+ membl = MEMNEXT(membl);
- while (membl) {
- pb->name = membl->name;
- pb->len = membl->len;
- pb->items = 1;
+ while (membl) {
+ pb->name = membl->name;
+ pb->len = membl->len;
+ pb->items = 1;
- totpb++;
- pb++;
+ totpb++;
+ pb++;
#ifdef USE_MALLOC_USABLE_SIZE
- if (!membl->mmap && membl->alignment == 0) {
- mem_in_use_slop += (sizeof(MemHead) + sizeof(MemTail) +
- malloc_usable_size((void *)membl)) - membl->len;
- }
+ if (!membl->mmap && membl->alignment == 0) {
+ mem_in_use_slop += (sizeof(MemHead) + sizeof(MemTail) + malloc_usable_size((void *)membl)) -
+ membl->len;
+ }
#endif
- if (membl->next)
- membl = MEMNEXT(membl->next);
- else break;
- }
-
- /* sort by name and add together blocks with the same name */
- qsort(printblock, totpb, sizeof(MemPrintBlock), compare_name);
- for (a = 0, b = 0; a < totpb; a++) {
- if (a == b) {
- continue;
- }
- else if (strcmp(printblock[a].name, printblock[b].name) == 0) {
- printblock[b].len += printblock[a].len;
- printblock[b].items++;
- }
- else {
- b++;
- memcpy(&printblock[b], &printblock[a], sizeof(MemPrintBlock));
- }
- }
- totpb = b + 1;
-
- /* sort by length and print */
- qsort(printblock, totpb, sizeof(MemPrintBlock), compare_len);
- printf("\ntotal memory len: %.3f MB\n",
- (double)mem_in_use / (double)(1024 * 1024));
- printf("peak memory len: %.3f MB\n",
- (double)peak_mem / (double)(1024 * 1024));
- printf("slop memory len: %.3f MB\n",
- (double)mem_in_use_slop / (double)(1024 * 1024));
- printf(" ITEMS TOTAL-MiB AVERAGE-KiB TYPE\n");
- for (a = 0, pb = printblock; a < totpb; a++, pb++) {
- printf("%6d (%8.3f %8.3f) %s\n",
- pb->items, (double)pb->len / (double)(1024 * 1024),
- (double)pb->len / 1024.0 / (double)pb->items, pb->name);
- }
- free(printblock);
-
- mem_unlock_thread();
+ if (membl->next)
+ membl = MEMNEXT(membl->next);
+ else
+ break;
+ }
+
+ /* sort by name and add together blocks with the same name */
+ qsort(printblock, totpb, sizeof(MemPrintBlock), compare_name);
+ for (a = 0, b = 0; a < totpb; a++) {
+ if (a == b) {
+ continue;
+ }
+ else if (strcmp(printblock[a].name, printblock[b].name) == 0) {
+ printblock[b].len += printblock[a].len;
+ printblock[b].items++;
+ }
+ else {
+ b++;
+ memcpy(&printblock[b], &printblock[a], sizeof(MemPrintBlock));
+ }
+ }
+ totpb = b + 1;
+
+ /* sort by length and print */
+ qsort(printblock, totpb, sizeof(MemPrintBlock), compare_len);
+ printf("\ntotal memory len: %.3f MB\n", (double)mem_in_use / (double)(1024 * 1024));
+ printf("peak memory len: %.3f MB\n", (double)peak_mem / (double)(1024 * 1024));
+ printf("slop memory len: %.3f MB\n", (double)mem_in_use_slop / (double)(1024 * 1024));
+ printf(" ITEMS TOTAL-MiB AVERAGE-KiB TYPE\n");
+ for (a = 0, pb = printblock; a < totpb; a++, pb++) {
+ printf("%6d (%8.3f %8.3f) %s\n",
+ pb->items,
+ (double)pb->len / (double)(1024 * 1024),
+ (double)pb->len / 1024.0 / (double)pb->items,
+ pb->name);
+ }
+ free(printblock);
+
+ mem_unlock_thread();
#ifdef HAVE_MALLOC_STATS
- printf("System Statistics:\n");
- malloc_stats();
+ printf("System Statistics:\n");
+ malloc_stats();
#endif
}
static const char mem_printmemlist_pydict_script[] =
-"mb_userinfo = {}\n"
-"totmem = 0\n"
-"for mb_item in membase:\n"
-" mb_item_user_size = mb_userinfo.setdefault(mb_item['name'], [0,0])\n"
-" mb_item_user_size[0] += 1 # Add a user\n"
-" mb_item_user_size[1] += mb_item['len'] # Increment the size\n"
-" totmem += mb_item['len']\n"
-"print('(membase) items:', len(membase), '| unique-names:',\n"
-" len(mb_userinfo), '| total-mem:', totmem)\n"
-"mb_userinfo_sort = list(mb_userinfo.items())\n"
-"for sort_name, sort_func in (('size', lambda a: -a[1][1]),\n"
-" ('users', lambda a: -a[1][0]),\n"
-" ('name', lambda a: a[0])):\n"
-" print('\\nSorting by:', sort_name)\n"
-" mb_userinfo_sort.sort(key = sort_func)\n"
-" for item in mb_userinfo_sort:\n"
-" print('name:%%s, users:%%i, len:%%i' %%\n"
-" (item[0], item[1][0], item[1][1]))\n";
+ "mb_userinfo = {}\n"
+ "totmem = 0\n"
+ "for mb_item in membase:\n"
+ " mb_item_user_size = mb_userinfo.setdefault(mb_item['name'], [0,0])\n"
+ " mb_item_user_size[0] += 1 # Add a user\n"
+ " mb_item_user_size[1] += mb_item['len'] # Increment the size\n"
+ " totmem += mb_item['len']\n"
+ "print('(membase) items:', len(membase), '| unique-names:',\n"
+ " len(mb_userinfo), '| total-mem:', totmem)\n"
+ "mb_userinfo_sort = list(mb_userinfo.items())\n"
+ "for sort_name, sort_func in (('size', lambda a: -a[1][1]),\n"
+ " ('users', lambda a: -a[1][0]),\n"
+ " ('name', lambda a: a[0])):\n"
+ " print('\\nSorting by:', sort_name)\n"
+ " mb_userinfo_sort.sort(key = sort_func)\n"
+ " for item in mb_userinfo_sort:\n"
+ " print('name:%%s, users:%%i, len:%%i' %%\n"
+ " (item[0], item[1][0], item[1][1]))\n";
/* Prints in python syntax for easy */
static void MEM_guarded_printmemlist_internal(int pydict)
{
- MemHead *membl;
-
- mem_lock_thread();
-
- membl = membase->first;
- if (membl) membl = MEMNEXT(membl);
-
- if (pydict) {
- print_error("# membase_debug.py\n");
- print_error("membase = [\n");
- }
- while (membl) {
- if (pydict) {
- print_error(" {'len':" SIZET_FORMAT ", "
- "'name':'''%s''', "
- "'pointer':'%p'},\n",
- SIZET_ARG(membl->len), membl->name, (void *)(membl + 1));
- }
- else {
+ MemHead *membl;
+
+ mem_lock_thread();
+
+ membl = membase->first;
+ if (membl)
+ membl = MEMNEXT(membl);
+
+ if (pydict) {
+ print_error("# membase_debug.py\n");
+ print_error("membase = [\n");
+ }
+ while (membl) {
+ if (pydict) {
+ print_error(" {'len':" SIZET_FORMAT
+ ", "
+ "'name':'''%s''', "
+ "'pointer':'%p'},\n",
+ SIZET_ARG(membl->len),
+ membl->name,
+ (void *)(membl + 1));
+ }
+ else {
#ifdef DEBUG_MEMCOUNTER
- print_error("%s len: " SIZET_FORMAT " %p, count: %d\n",
- membl->name, SIZET_ARG(membl->len), membl + 1,
- membl->_count);
+ print_error("%s len: " SIZET_FORMAT " %p, count: %d\n",
+ membl->name,
+ SIZET_ARG(membl->len),
+ membl + 1,
+ membl->_count);
#else
- print_error("%s len: " SIZET_FORMAT " %p\n",
- membl->name, SIZET_ARG(membl->len), (void *)(membl + 1));
+ print_error("%s len: " SIZET_FORMAT " %p\n",
+ membl->name,
+ SIZET_ARG(membl->len),
+ (void *)(membl + 1));
#endif
#ifdef DEBUG_BACKTRACE
- print_memhead_backtrace(membl);
+ print_memhead_backtrace(membl);
#endif
- }
- if (membl->next)
- membl = MEMNEXT(membl->next);
- else break;
- }
- if (pydict) {
- print_error("]\n\n");
- print_error(mem_printmemlist_pydict_script);
- }
-
- mem_unlock_thread();
+ }
+ if (membl->next)
+ membl = MEMNEXT(membl->next);
+ else
+ break;
+ }
+ if (pydict) {
+ print_error("]\n\n");
+ print_error(mem_printmemlist_pydict_script);
+ }
+
+ mem_unlock_thread();
}
void MEM_guarded_callbackmemlist(void (*func)(void *))
{
- MemHead *membl;
+ MemHead *membl;
- mem_lock_thread();
+ mem_lock_thread();
- membl = membase->first;
- if (membl) membl = MEMNEXT(membl);
+ membl = membase->first;
+ if (membl)
+ membl = MEMNEXT(membl);
- while (membl) {
- func(membl + 1);
- if (membl->next)
- membl = MEMNEXT(membl->next);
- else break;
- }
+ while (membl) {
+ func(membl + 1);
+ if (membl->next)
+ membl = MEMNEXT(membl->next);
+ else
+ break;
+ }
- mem_unlock_thread();
+ mem_unlock_thread();
}
#if 0
short MEM_guarded_testN(void *vmemh)
{
- MemHead *membl;
+ MemHead *membl;
- mem_lock_thread();
+ mem_lock_thread();
- membl = membase->first;
- if (membl) membl = MEMNEXT(membl);
+ membl = membase->first;
+ if (membl) membl = MEMNEXT(membl);
- while (membl) {
- if (vmemh == membl + 1) {
- mem_unlock_thread();
- return 1;
- }
+ while (membl) {
+ if (vmemh == membl + 1) {
+ mem_unlock_thread();
+ return 1;
+ }
- if (membl->next)
- membl = MEMNEXT(membl->next);
- else break;
- }
+ if (membl->next)
+ membl = MEMNEXT(membl->next);
+ else break;
+ }
- mem_unlock_thread();
+ mem_unlock_thread();
- print_error("Memoryblock %p: pointer not in memlist\n", vmemh);
- return 0;
+ print_error("Memoryblock %p: pointer not in memlist\n", vmemh);
+ return 0;
}
#endif
void MEM_guarded_printmemlist(void)
{
- MEM_guarded_printmemlist_internal(0);
+ MEM_guarded_printmemlist_internal(0);
}
void MEM_guarded_printmemlist_pydict(void)
{
- MEM_guarded_printmemlist_internal(1);
+ MEM_guarded_printmemlist_internal(1);
}
void MEM_guarded_freeN(void *vmemh)
{
- MemTail *memt;
- MemHead *memh = vmemh;
- const char *name;
-
- if (memh == NULL) {
- MemorY_ErroR("free", "attempt to free NULL pointer");
- /* print_error(err_stream, "%d\n", (memh+4000)->tag1); */
- return;
- }
-
- if (sizeof(intptr_t) == 8) {
- if (((intptr_t) memh) & 0x7) {
- MemorY_ErroR("free", "attempt to free illegal pointer");
- return;
- }
- }
- else {
- if (((intptr_t) memh) & 0x3) {
- MemorY_ErroR("free", "attempt to free illegal pointer");
- return;
- }
- }
-
- memh--;
- if (memh->tag1 == MEMFREE && memh->tag2 == MEMFREE) {
- MemorY_ErroR(memh->name, "double free");
- return;
- }
-
- if ((memh->tag1 == MEMTAG1) &&
- (memh->tag2 == MEMTAG2) &&
- ((memh->len & 0x3) == 0))
- {
- memt = (MemTail *)(((char *) memh) + sizeof(MemHead) + memh->len);
- if (memt->tag3 == MEMTAG3) {
-
- memh->tag1 = MEMFREE;
- memh->tag2 = MEMFREE;
- memt->tag3 = MEMFREE;
- /* after tags !!! */
- rem_memblock(memh);
-
- return;
- }
- MemorY_ErroR(memh->name, "end corrupt");
- name = check_memlist(memh);
- if (name != NULL) {
- if (name != memh->name) MemorY_ErroR(name, "is also corrupt");
- }
- }
- else {
- mem_lock_thread();
- name = check_memlist(memh);
- mem_unlock_thread();
- if (name == NULL)
- MemorY_ErroR("free", "pointer not in memlist");
- else
- MemorY_ErroR(name, "error in header");
- }
-
- totblock--;
- /* here a DUMP should happen */
-
- return;
+ MemTail *memt;
+ MemHead *memh = vmemh;
+ const char *name;
+
+ if (memh == NULL) {
+ MemorY_ErroR("free", "attempt to free NULL pointer");
+ /* print_error(err_stream, "%d\n", (memh+4000)->tag1); */
+ return;
+ }
+
+ if (sizeof(intptr_t) == 8) {
+ if (((intptr_t)memh) & 0x7) {
+ MemorY_ErroR("free", "attempt to free illegal pointer");
+ return;
+ }
+ }
+ else {
+ if (((intptr_t)memh) & 0x3) {
+ MemorY_ErroR("free", "attempt to free illegal pointer");
+ return;
+ }
+ }
+
+ memh--;
+ if (memh->tag1 == MEMFREE && memh->tag2 == MEMFREE) {
+ MemorY_ErroR(memh->name, "double free");
+ return;
+ }
+
+ if ((memh->tag1 == MEMTAG1) && (memh->tag2 == MEMTAG2) && ((memh->len & 0x3) == 0)) {
+ memt = (MemTail *)(((char *)memh) + sizeof(MemHead) + memh->len);
+ if (memt->tag3 == MEMTAG3) {
+
+ memh->tag1 = MEMFREE;
+ memh->tag2 = MEMFREE;
+ memt->tag3 = MEMFREE;
+ /* after tags !!! */
+ rem_memblock(memh);
+
+ return;
+ }
+ MemorY_ErroR(memh->name, "end corrupt");
+ name = check_memlist(memh);
+ if (name != NULL) {
+ if (name != memh->name)
+ MemorY_ErroR(name, "is also corrupt");
+ }
+ }
+ else {
+ mem_lock_thread();
+ name = check_memlist(memh);
+ mem_unlock_thread();
+ if (name == NULL)
+ MemorY_ErroR("free", "pointer not in memlist");
+ else
+ MemorY_ErroR(name, "error in header");
+ }
+
+ totblock--;
+ /* here a DUMP should happen */
+
+ return;
}
/* --------------------------------------------------------------------- */
@@ -980,243 +1008,271 @@ void MEM_guarded_freeN(void *vmemh)
static void addtail(volatile localListBase *listbase, void *vlink)
{
- struct localLink *link = vlink;
+ struct localLink *link = vlink;
- /* for a generic API error checks here is fine but
- * the limited use here they will never be NULL */
+ /* for a generic API error checks here is fine but
+ * the limited use here they will never be NULL */
#if 0
- if (link == NULL) return;
- if (listbase == NULL) return;
+ if (link == NULL) return;
+ if (listbase == NULL) return;
#endif
- link->next = NULL;
- link->prev = listbase->last;
+ link->next = NULL;
+ link->prev = listbase->last;
- if (listbase->last) ((struct localLink *)listbase->last)->next = link;
- if (listbase->first == NULL) listbase->first = link;
- listbase->last = link;
+ if (listbase->last)
+ ((struct localLink *)listbase->last)->next = link;
+ if (listbase->first == NULL)
+ listbase->first = link;
+ listbase->last = link;
}
static void remlink(volatile localListBase *listbase, void *vlink)
{
- struct localLink *link = vlink;
+ struct localLink *link = vlink;
- /* for a generic API error checks here is fine but
- * the limited use here they will never be NULL */
+ /* for a generic API error checks here is fine but
+ * the limited use here they will never be NULL */
#if 0
- if (link == NULL) return;
- if (listbase == NULL) return;
+ if (link == NULL) return;
+ if (listbase == NULL) return;
#endif
- if (link->next) link->next->prev = link->prev;
- if (link->prev) link->prev->next = link->next;
+ if (link->next)
+ link->next->prev = link->prev;
+ if (link->prev)
+ link->prev->next = link->next;
- if (listbase->last == link) listbase->last = link->prev;
- if (listbase->first == link) listbase->first = link->next;
+ if (listbase->last == link)
+ listbase->last = link->prev;
+ if (listbase->first == link)
+ listbase->first = link->next;
}
static void rem_memblock(MemHead *memh)
{
- mem_lock_thread();
- remlink(membase, &memh->next);
- if (memh->prev) {
- if (memh->next)
- MEMNEXT(memh->prev)->nextname = MEMNEXT(memh->next)->name;
- else
- MEMNEXT(memh->prev)->nextname = NULL;
- }
- mem_unlock_thread();
-
- atomic_sub_and_fetch_u(&totblock, 1);
- atomic_sub_and_fetch_z(&mem_in_use, memh->len);
+ mem_lock_thread();
+ remlink(membase, &memh->next);
+ if (memh->prev) {
+ if (memh->next)
+ MEMNEXT(memh->prev)->nextname = MEMNEXT(memh->next)->name;
+ else
+ MEMNEXT(memh->prev)->nextname = NULL;
+ }
+ mem_unlock_thread();
+
+ atomic_sub_and_fetch_u(&totblock, 1);
+ atomic_sub_and_fetch_z(&mem_in_use, memh->len);
#ifdef DEBUG_MEMDUPLINAME
- if (memh->need_free_name)
- free((char *) memh->name);
+ if (memh->need_free_name)
+ free((char *)memh->name);
#endif
- if (memh->mmap) {
- atomic_sub_and_fetch_z(&mmap_in_use, memh->len);
+ if (memh->mmap) {
+ atomic_sub_and_fetch_z(&mmap_in_use, memh->len);
#if defined(WIN32)
- /* our windows mmap implementation is not thread safe */
- mem_lock_thread();
+ /* our windows mmap implementation is not thread safe */
+ mem_lock_thread();
#endif
- if (munmap(memh, memh->len + sizeof(MemHead) + sizeof(MemTail)))
- printf("Couldn't unmap memory %s\n", memh->name);
+ if (munmap(memh, memh->len + sizeof(MemHead) + sizeof(MemTail)))
+ printf("Couldn't unmap memory %s\n", memh->name);
#if defined(WIN32)
- mem_unlock_thread();
+ mem_unlock_thread();
#endif
- }
- else {
- if (UNLIKELY(malloc_debug_memset && memh->len))
- memset(memh + 1, 255, memh->len);
- if (LIKELY(memh->alignment == 0)) {
- free(memh);
- }
- else {
- aligned_free(MEMHEAD_REAL_PTR(memh));
- }
- }
+ }
+ else {
+ if (UNLIKELY(malloc_debug_memset && memh->len))
+ memset(memh + 1, 255, memh->len);
+ if (LIKELY(memh->alignment == 0)) {
+ free(memh);
+ }
+ else {
+ aligned_free(MEMHEAD_REAL_PTR(memh));
+ }
+ }
}
static void MemorY_ErroR(const char *block, const char *error)
{
- print_error("Memoryblock %s: %s\n", block, error);
+ print_error("Memoryblock %s: %s\n", block, error);
#ifdef WITH_ASSERT_ABORT
- abort();
+ abort();
#endif
}
static const char *check_memlist(MemHead *memh)
{
- MemHead *forw, *back, *forwok, *backok;
- const char *name;
-
- forw = membase->first;
- if (forw) forw = MEMNEXT(forw);
- forwok = NULL;
- while (forw) {
- if (forw->tag1 != MEMTAG1 || forw->tag2 != MEMTAG2) break;
- forwok = forw;
- if (forw->next) forw = MEMNEXT(forw->next);
- else forw = NULL;
- }
-
- back = (MemHead *) membase->last;
- if (back) back = MEMNEXT(back);
- backok = NULL;
- while (back) {
- if (back->tag1 != MEMTAG1 || back->tag2 != MEMTAG2) break;
- backok = back;
- if (back->prev) back = MEMNEXT(back->prev);
- else back = NULL;
- }
-
- if (forw != back) return ("MORE THAN 1 MEMORYBLOCK CORRUPT");
-
- if (forw == NULL && back == NULL) {
- /* no wrong headers found then but in search of memblock */
-
- forw = membase->first;
- if (forw) forw = MEMNEXT(forw);
- forwok = NULL;
- while (forw) {
- if (forw == memh) break;
- if (forw->tag1 != MEMTAG1 || forw->tag2 != MEMTAG2) break;
- forwok = forw;
- if (forw->next) forw = MEMNEXT(forw->next);
- else forw = NULL;
- }
- if (forw == NULL) return NULL;
-
- back = (MemHead *) membase->last;
- if (back) back = MEMNEXT(back);
- backok = NULL;
- while (back) {
- if (back == memh) break;
- if (back->tag1 != MEMTAG1 || back->tag2 != MEMTAG2) break;
- backok = back;
- if (back->prev) back = MEMNEXT(back->prev);
- else back = NULL;
- }
- }
-
- if (forwok) name = forwok->nextname;
- else name = "No name found";
-
- if (forw == memh) {
- /* to be sure but this block is removed from the list */
- if (forwok) {
- if (backok) {
- forwok->next = (MemHead *)&backok->next;
- backok->prev = (MemHead *)&forwok->next;
- forwok->nextname = backok->name;
- }
- else {
- forwok->next = NULL;
- membase->last = (struct localLink *) &forwok->next;
- }
- }
- else {
- if (backok) {
- backok->prev = NULL;
- membase->first = &backok->next;
- }
- else {
- membase->first = membase->last = NULL;
- }
- }
- }
- else {
- MemorY_ErroR(name, "Additional error in header");
- return("Additional error in header");
- }
-
- return(name);
+ MemHead *forw, *back, *forwok, *backok;
+ const char *name;
+
+ forw = membase->first;
+ if (forw)
+ forw = MEMNEXT(forw);
+ forwok = NULL;
+ while (forw) {
+ if (forw->tag1 != MEMTAG1 || forw->tag2 != MEMTAG2)
+ break;
+ forwok = forw;
+ if (forw->next)
+ forw = MEMNEXT(forw->next);
+ else
+ forw = NULL;
+ }
+
+ back = (MemHead *)membase->last;
+ if (back)
+ back = MEMNEXT(back);
+ backok = NULL;
+ while (back) {
+ if (back->tag1 != MEMTAG1 || back->tag2 != MEMTAG2)
+ break;
+ backok = back;
+ if (back->prev)
+ back = MEMNEXT(back->prev);
+ else
+ back = NULL;
+ }
+
+ if (forw != back)
+ return ("MORE THAN 1 MEMORYBLOCK CORRUPT");
+
+ if (forw == NULL && back == NULL) {
+ /* no wrong headers found then but in search of memblock */
+
+ forw = membase->first;
+ if (forw)
+ forw = MEMNEXT(forw);
+ forwok = NULL;
+ while (forw) {
+ if (forw == memh)
+ break;
+ if (forw->tag1 != MEMTAG1 || forw->tag2 != MEMTAG2)
+ break;
+ forwok = forw;
+ if (forw->next)
+ forw = MEMNEXT(forw->next);
+ else
+ forw = NULL;
+ }
+ if (forw == NULL)
+ return NULL;
+
+ back = (MemHead *)membase->last;
+ if (back)
+ back = MEMNEXT(back);
+ backok = NULL;
+ while (back) {
+ if (back == memh)
+ break;
+ if (back->tag1 != MEMTAG1 || back->tag2 != MEMTAG2)
+ break;
+ backok = back;
+ if (back->prev)
+ back = MEMNEXT(back->prev);
+ else
+ back = NULL;
+ }
+ }
+
+ if (forwok)
+ name = forwok->nextname;
+ else
+ name = "No name found";
+
+ if (forw == memh) {
+ /* to be sure but this block is removed from the list */
+ if (forwok) {
+ if (backok) {
+ forwok->next = (MemHead *)&backok->next;
+ backok->prev = (MemHead *)&forwok->next;
+ forwok->nextname = backok->name;
+ }
+ else {
+ forwok->next = NULL;
+ membase->last = (struct localLink *)&forwok->next;
+ }
+ }
+ else {
+ if (backok) {
+ backok->prev = NULL;
+ membase->first = &backok->next;
+ }
+ else {
+ membase->first = membase->last = NULL;
+ }
+ }
+ }
+ else {
+ MemorY_ErroR(name, "Additional error in header");
+ return ("Additional error in header");
+ }
+
+ return (name);
}
size_t MEM_guarded_get_peak_memory(void)
{
- size_t _peak_mem;
+ size_t _peak_mem;
- mem_lock_thread();
- _peak_mem = peak_mem;
- mem_unlock_thread();
+ mem_lock_thread();
+ _peak_mem = peak_mem;
+ mem_unlock_thread();
- return _peak_mem;
+ return _peak_mem;
}
void MEM_guarded_reset_peak_memory(void)
{
- mem_lock_thread();
- peak_mem = mem_in_use;
- mem_unlock_thread();
+ mem_lock_thread();
+ peak_mem = mem_in_use;
+ mem_unlock_thread();
}
size_t MEM_guarded_get_memory_in_use(void)
{
- size_t _mem_in_use;
+ size_t _mem_in_use;
- mem_lock_thread();
- _mem_in_use = mem_in_use;
- mem_unlock_thread();
+ mem_lock_thread();
+ _mem_in_use = mem_in_use;
+ mem_unlock_thread();
- return _mem_in_use;
+ return _mem_in_use;
}
size_t MEM_guarded_get_mapped_memory_in_use(void)
{
- size_t _mmap_in_use;
+ size_t _mmap_in_use;
- mem_lock_thread();
- _mmap_in_use = mmap_in_use;
- mem_unlock_thread();
+ mem_lock_thread();
+ _mmap_in_use = mmap_in_use;
+ mem_unlock_thread();
- return _mmap_in_use;
+ return _mmap_in_use;
}
unsigned int MEM_guarded_get_memory_blocks_in_use(void)
{
- unsigned int _totblock;
+ unsigned int _totblock;
- mem_lock_thread();
- _totblock = totblock;
- mem_unlock_thread();
+ mem_lock_thread();
+ _totblock = totblock;
+ mem_unlock_thread();
- return _totblock;
+ return _totblock;
}
#ifndef NDEBUG
const char *MEM_guarded_name_ptr(void *vmemh)
{
- if (vmemh) {
- MemHead *memh = vmemh;
- memh--;
- return memh->name;
- }
- else {
- return "MEM_guarded_name_ptr(NULL)";
- }
+ if (vmemh) {
+ MemHead *memh = vmemh;
+ memh--;
+ return memh->name;
+ }
+ else {
+ return "MEM_guarded_name_ptr(NULL)";
+ }
}
-#endif /* NDEBUG */
+#endif /* NDEBUG */
diff --git a/intern/guardedalloc/intern/mallocn_inline.h b/intern/guardedalloc/intern/mallocn_inline.h
index 064cc063668..f8bb7861fc9 100644
--- a/intern/guardedalloc/intern/mallocn_inline.h
+++ b/intern/guardedalloc/intern/mallocn_inline.h
@@ -35,21 +35,21 @@
MEM_INLINE bool MEM_size_safe_multiply(size_t a, size_t b, size_t *result)
{
- /* A size_t with its high-half bits all set to 1. */
- const size_t high_bits = SIZE_MAX << (sizeof(size_t) * 8 / 2);
- *result = a * b;
+ /* A size_t with its high-half bits all set to 1. */
+ const size_t high_bits = SIZE_MAX << (sizeof(size_t) * 8 / 2);
+ *result = a * b;
- if (UNLIKELY(*result == 0)) {
- return (a == 0 || b == 0);
- }
+ if (UNLIKELY(*result == 0)) {
+ return (a == 0 || b == 0);
+ }
- /*
- * We got a non-zero size, but we don't know if we overflowed to get
- * there. To avoid having to do a divide, we'll be clever and note that
- * if both A and B can be represented in N/2 bits, then their product
- * can be represented in N bits (without the possibility of overflow).
- */
- return ((high_bits & (a | b)) == 0 || (*result / b == a));
+ /*
+ * We got a non-zero size, but we don't know if we overflowed to get
+ * there. To avoid having to do a divide, we'll be clever and note that
+ * if both A and B can be represented in N/2 bits, then their product
+ * can be represented in N bits (without the possibility of overflow).
+ */
+ return ((high_bits & (a | b)) == 0 || (*result / b == a));
}
-#endif /* __MALLOCN_INLINE_H__ */
+#endif /* __MALLOCN_INLINE_H__ */
diff --git a/intern/guardedalloc/intern/mallocn_intern.h b/intern/guardedalloc/intern/mallocn_intern.h
index 7479f11f70c..e6e090703d4 100644
--- a/intern/guardedalloc/intern/mallocn_intern.h
+++ b/intern/guardedalloc/intern/mallocn_intern.h
@@ -32,15 +32,16 @@
#endif
#ifdef __GNUC__
-# define UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
+# define UNUSED(x) UNUSED_##x __attribute__((__unused__))
#else
-# define UNUSED(x) UNUSED_ ## x
+# define UNUSED(x) UNUSED_##x
#endif
#undef HAVE_MALLOC_STATS
-#define USE_MALLOC_USABLE_SIZE /* internal, when we have malloc_usable_size() */
+#define USE_MALLOC_USABLE_SIZE /* internal, when we have malloc_usable_size() */
-#if defined(__linux__) || (defined(__FreeBSD_kernel__) && !defined(__FreeBSD__)) || defined(__GLIBC__)
+#if defined(__linux__) || (defined(__FreeBSD_kernel__) && !defined(__FreeBSD__)) || \
+ defined(__GLIBC__)
# include <malloc.h>
# define HAVE_MALLOC_STATS
#elif defined(__FreeBSD__)
@@ -71,11 +72,11 @@ size_t malloc_usable_size(void *ptr);
#define SIZET_ALIGN_4(len) ((len + 3) & ~(size_t)3)
#ifdef __GNUC__
-# define LIKELY(x) __builtin_expect(!!(x), 1)
-# define UNLIKELY(x) __builtin_expect(!!(x), 0)
+# define LIKELY(x) __builtin_expect(!!(x), 1)
+# define UNLIKELY(x) __builtin_expect(!!(x), 0)
#else
-# define LIKELY(x) (x)
-# define UNLIKELY(x) (x)
+# define LIKELY(x) (x)
+# define UNLIKELY(x) (x)
#endif
#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__NetBSD__)
@@ -95,10 +96,11 @@ size_t malloc_usable_size(void *ptr);
# define MEM_INLINE static inline
#endif
-#define IS_POW2(a) (((a) & ((a) - 1)) == 0)
+#define IS_POW2(a) (((a) & ((a)-1)) == 0)
/* Extra padding which needs to be applied on MemHead to make it aligned. */
-#define MEMHEAD_ALIGN_PADDING(alignment) ((size_t)alignment - (sizeof(MemHeadAligned) % (size_t)alignment))
+#define MEMHEAD_ALIGN_PADDING(alignment) \
+ ((size_t)alignment - (sizeof(MemHeadAligned) % (size_t)alignment))
/* Real pointer returned by the malloc or aligned_alloc. */
#define MEMHEAD_REAL_PTR(memh) ((char *)memh - MEMHEAD_ALIGN_PADDING(memh->alignment))
@@ -112,14 +114,33 @@ void aligned_free(void *ptr);
size_t MEM_lockfree_allocN_len(const void *vmemh) ATTR_WARN_UNUSED_RESULT;
void MEM_lockfree_freeN(void *vmemh);
void *MEM_lockfree_dupallocN(const void *vmemh) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
-void *MEM_lockfree_reallocN_id(void *vmemh, size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(2);
-void *MEM_lockfree_recallocN_id(void *vmemh, size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(2);
-void *MEM_lockfree_callocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
-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);
-void *MEM_lockfree_mallocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
-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);
-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);
-void *MEM_lockfree_mapallocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
+void *MEM_lockfree_reallocN_id(void *vmemh,
+ size_t len,
+ const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(2);
+void *MEM_lockfree_recallocN_id(void *vmemh,
+ size_t len,
+ const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(2);
+void *MEM_lockfree_callocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
+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);
+void *MEM_lockfree_mallocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
+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);
+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);
+void *MEM_lockfree_mapallocN(size_t len,
+ const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
void MEM_lockfree_printmemlist_pydict(void);
void MEM_lockfree_printmemlist(void);
void MEM_lockfree_callbackmemlist(void (*func)(void *));
@@ -141,14 +162,33 @@ const char *MEM_lockfree_name_ptr(void *vmemh);
size_t MEM_guarded_allocN_len(const void *vmemh) ATTR_WARN_UNUSED_RESULT;
void MEM_guarded_freeN(void *vmemh);
void *MEM_guarded_dupallocN(const void *vmemh) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
-void *MEM_guarded_reallocN_id(void *vmemh, size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(2);
-void *MEM_guarded_recallocN_id(void *vmemh, size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(2);
-void *MEM_guarded_callocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
-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);
-void *MEM_guarded_mallocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
-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);
-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);
-void *MEM_guarded_mapallocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
+void *MEM_guarded_reallocN_id(void *vmemh,
+ size_t len,
+ const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(2);
+void *MEM_guarded_recallocN_id(void *vmemh,
+ size_t len,
+ const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(2);
+void *MEM_guarded_callocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
+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);
+void *MEM_guarded_mallocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
+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);
+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);
+void *MEM_guarded_mapallocN(size_t len,
+ const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
+ ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
void MEM_guarded_printmemlist_pydict(void);
void MEM_guarded_printmemlist(void);
void MEM_guarded_callbackmemlist(void (*func)(void *));
@@ -166,4 +206,4 @@ size_t MEM_guarded_get_peak_memory(void) ATTR_WARN_UNUSED_RESULT;
const char *MEM_guarded_name_ptr(void *vmemh);
#endif
-#endif /* __MALLOCN_INTERN_H__ */
+#endif /* __MALLOCN_INTERN_H__ */
diff --git a/intern/guardedalloc/intern/mallocn_lockfree_impl.c b/intern/guardedalloc/intern/mallocn_lockfree_impl.c
index 9ca0bc38b66..e8fd8de738b 100644
--- a/intern/guardedalloc/intern/mallocn_lockfree_impl.c
+++ b/intern/guardedalloc/intern/mallocn_lockfree_impl.c
@@ -34,13 +34,13 @@
#include "mallocn_intern.h"
typedef struct MemHead {
- /* Length of allocated memory block. */
- size_t len;
+ /* Length of allocated memory block. */
+ size_t len;
} MemHead;
typedef struct MemHeadAligned {
- short alignment;
- size_t len;
+ short alignment;
+ size_t len;
} MemHeadAligned;
static unsigned int totblock = 0;
@@ -52,15 +52,15 @@ static void (*thread_lock_callback)(void) = NULL;
static void (*thread_unlock_callback)(void) = NULL;
enum {
- MEMHEAD_MMAP_FLAG = 1,
- MEMHEAD_ALIGN_FLAG = 2,
+ MEMHEAD_MMAP_FLAG = 1,
+ MEMHEAD_ALIGN_FLAG = 2,
};
-#define MEMHEAD_FROM_PTR(ptr) (((MemHead*) ptr) - 1)
+#define MEMHEAD_FROM_PTR(ptr) (((MemHead *)ptr) - 1)
#define PTR_FROM_MEMHEAD(memhead) (memhead + 1)
-#define MEMHEAD_ALIGNED_FROM_PTR(ptr) (((MemHeadAligned*) ptr) - 1)
-#define MEMHEAD_IS_MMAP(memhead) ((memhead)->len & (size_t) MEMHEAD_MMAP_FLAG)
-#define MEMHEAD_IS_ALIGNED(memhead) ((memhead)->len & (size_t) MEMHEAD_ALIGN_FLAG)
+#define MEMHEAD_ALIGNED_FROM_PTR(ptr) (((MemHeadAligned *)ptr) - 1)
+#define MEMHEAD_IS_MMAP(memhead) ((memhead)->len & (size_t)MEMHEAD_MMAP_FLAG)
+#define MEMHEAD_IS_ALIGNED(memhead) ((memhead)->len & (size_t)MEMHEAD_ALIGN_FLAG)
/* Uncomment this to have proper peak counter. */
#define USE_ATOMIC_MAX
@@ -68,365 +68,371 @@ enum {
MEM_INLINE void update_maximum(size_t *maximum_value, size_t value)
{
#ifdef USE_ATOMIC_MAX
- atomic_fetch_and_update_max_z(maximum_value, value);
+ atomic_fetch_and_update_max_z(maximum_value, value);
#else
- *maximum_value = value > *maximum_value ? value : *maximum_value;
+ *maximum_value = value > *maximum_value ? value : *maximum_value;
#endif
}
#ifdef __GNUC__
-__attribute__ ((format(printf, 1, 2)))
+__attribute__((format(printf, 1, 2)))
#endif
-static void print_error(const char *str, ...)
+static void
+print_error(const char *str, ...)
{
- char buf[512];
- va_list ap;
+ char buf[512];
+ va_list ap;
- va_start(ap, str);
- vsnprintf(buf, sizeof(buf), str, ap);
- va_end(ap);
- buf[sizeof(buf) - 1] = '\0';
+ va_start(ap, str);
+ vsnprintf(buf, sizeof(buf), str, ap);
+ va_end(ap);
+ buf[sizeof(buf) - 1] = '\0';
- if (error_callback) {
- error_callback(buf);
- }
+ if (error_callback) {
+ error_callback(buf);
+ }
}
#if defined(WIN32)
static void mem_lock_thread(void)
{
- if (thread_lock_callback)
- thread_lock_callback();
+ if (thread_lock_callback)
+ thread_lock_callback();
}
static void mem_unlock_thread(void)
{
- if (thread_unlock_callback)
- thread_unlock_callback();
+ if (thread_unlock_callback)
+ thread_unlock_callback();
}
#endif
size_t MEM_lockfree_allocN_len(const void *vmemh)
{
- if (vmemh) {
- return MEMHEAD_FROM_PTR(vmemh)->len & ~((size_t) (MEMHEAD_MMAP_FLAG | MEMHEAD_ALIGN_FLAG));
- }
- else {
- return 0;
- }
+ if (vmemh) {
+ return MEMHEAD_FROM_PTR(vmemh)->len & ~((size_t)(MEMHEAD_MMAP_FLAG | MEMHEAD_ALIGN_FLAG));
+ }
+ else {
+ return 0;
+ }
}
void MEM_lockfree_freeN(void *vmemh)
{
- MemHead *memh = MEMHEAD_FROM_PTR(vmemh);
- size_t len = MEM_lockfree_allocN_len(vmemh);
+ MemHead *memh = MEMHEAD_FROM_PTR(vmemh);
+ size_t len = MEM_lockfree_allocN_len(vmemh);
- if (vmemh == NULL) {
- print_error("Attempt to free NULL pointer\n");
+ if (vmemh == NULL) {
+ print_error("Attempt to free NULL pointer\n");
#ifdef WITH_ASSERT_ABORT
- abort();
+ abort();
#endif
- return;
- }
+ return;
+ }
- atomic_sub_and_fetch_u(&totblock, 1);
- atomic_sub_and_fetch_z(&mem_in_use, len);
+ atomic_sub_and_fetch_u(&totblock, 1);
+ atomic_sub_and_fetch_z(&mem_in_use, len);
- if (MEMHEAD_IS_MMAP(memh)) {
- atomic_sub_and_fetch_z(&mmap_in_use, len);
+ if (MEMHEAD_IS_MMAP(memh)) {
+ atomic_sub_and_fetch_z(&mmap_in_use, len);
#if defined(WIN32)
- /* our windows mmap implementation is not thread safe */
- mem_lock_thread();
+ /* our windows mmap implementation is not thread safe */
+ mem_lock_thread();
#endif
- if (munmap(memh, len + sizeof(MemHead)))
- printf("Couldn't unmap memory\n");
+ if (munmap(memh, len + sizeof(MemHead)))
+ printf("Couldn't unmap memory\n");
#if defined(WIN32)
- mem_unlock_thread();
+ mem_unlock_thread();
#endif
- }
- else {
- if (UNLIKELY(malloc_debug_memset && len)) {
- memset(memh + 1, 255, len);
- }
- if (UNLIKELY(MEMHEAD_IS_ALIGNED(memh))) {
- MemHeadAligned *memh_aligned = MEMHEAD_ALIGNED_FROM_PTR(vmemh);
- aligned_free(MEMHEAD_REAL_PTR(memh_aligned));
- }
- else {
- free(memh);
- }
- }
+ }
+ else {
+ if (UNLIKELY(malloc_debug_memset && len)) {
+ memset(memh + 1, 255, len);
+ }
+ if (UNLIKELY(MEMHEAD_IS_ALIGNED(memh))) {
+ MemHeadAligned *memh_aligned = MEMHEAD_ALIGNED_FROM_PTR(vmemh);
+ aligned_free(MEMHEAD_REAL_PTR(memh_aligned));
+ }
+ else {
+ free(memh);
+ }
+ }
}
void *MEM_lockfree_dupallocN(const void *vmemh)
{
- void *newp = NULL;
- if (vmemh) {
- MemHead *memh = MEMHEAD_FROM_PTR(vmemh);
- const size_t prev_size = MEM_lockfree_allocN_len(vmemh);
- if (UNLIKELY(MEMHEAD_IS_MMAP(memh))) {
- newp = MEM_lockfree_mapallocN(prev_size, "dupli_mapalloc");
- }
- else if (UNLIKELY(MEMHEAD_IS_ALIGNED(memh))) {
- MemHeadAligned *memh_aligned = MEMHEAD_ALIGNED_FROM_PTR(vmemh);
- newp = MEM_lockfree_mallocN_aligned(
- prev_size,
- (size_t)memh_aligned->alignment,
- "dupli_malloc");
- }
- else {
- newp = MEM_lockfree_mallocN(prev_size, "dupli_malloc");
- }
- memcpy(newp, vmemh, prev_size);
- }
- return newp;
+ void *newp = NULL;
+ if (vmemh) {
+ MemHead *memh = MEMHEAD_FROM_PTR(vmemh);
+ const size_t prev_size = MEM_lockfree_allocN_len(vmemh);
+ if (UNLIKELY(MEMHEAD_IS_MMAP(memh))) {
+ newp = MEM_lockfree_mapallocN(prev_size, "dupli_mapalloc");
+ }
+ else if (UNLIKELY(MEMHEAD_IS_ALIGNED(memh))) {
+ MemHeadAligned *memh_aligned = MEMHEAD_ALIGNED_FROM_PTR(vmemh);
+ newp = MEM_lockfree_mallocN_aligned(
+ prev_size, (size_t)memh_aligned->alignment, "dupli_malloc");
+ }
+ else {
+ newp = MEM_lockfree_mallocN(prev_size, "dupli_malloc");
+ }
+ memcpy(newp, vmemh, prev_size);
+ }
+ return newp;
}
void *MEM_lockfree_reallocN_id(void *vmemh, size_t len, const char *str)
{
- void *newp = NULL;
-
- if (vmemh) {
- MemHead *memh = MEMHEAD_FROM_PTR(vmemh);
- size_t old_len = MEM_lockfree_allocN_len(vmemh);
-
- if (LIKELY(!MEMHEAD_IS_ALIGNED(memh))) {
- newp = MEM_lockfree_mallocN(len, "realloc");
- }
- else {
- MemHeadAligned *memh_aligned = MEMHEAD_ALIGNED_FROM_PTR(vmemh);
- newp = MEM_lockfree_mallocN_aligned(
- len,
- (size_t)memh_aligned->alignment,
- "realloc");
- }
-
- if (newp) {
- if (len < old_len) {
- /* shrink */
- memcpy(newp, vmemh, len);
- }
- else {
- /* grow (or remain same size) */
- memcpy(newp, vmemh, old_len);
- }
- }
-
- MEM_lockfree_freeN(vmemh);
- }
- else {
- newp = MEM_lockfree_mallocN(len, str);
- }
-
- return newp;
+ void *newp = NULL;
+
+ if (vmemh) {
+ MemHead *memh = MEMHEAD_FROM_PTR(vmemh);
+ size_t old_len = MEM_lockfree_allocN_len(vmemh);
+
+ if (LIKELY(!MEMHEAD_IS_ALIGNED(memh))) {
+ newp = MEM_lockfree_mallocN(len, "realloc");
+ }
+ else {
+ MemHeadAligned *memh_aligned = MEMHEAD_ALIGNED_FROM_PTR(vmemh);
+ newp = MEM_lockfree_mallocN_aligned(len, (size_t)memh_aligned->alignment, "realloc");
+ }
+
+ if (newp) {
+ if (len < old_len) {
+ /* shrink */
+ memcpy(newp, vmemh, len);
+ }
+ else {
+ /* grow (or remain same size) */
+ memcpy(newp, vmemh, old_len);
+ }
+ }
+
+ MEM_lockfree_freeN(vmemh);
+ }
+ else {
+ newp = MEM_lockfree_mallocN(len, str);
+ }
+
+ return newp;
}
void *MEM_lockfree_recallocN_id(void *vmemh, size_t len, const char *str)
{
- void *newp = NULL;
-
- if (vmemh) {
- MemHead *memh = MEMHEAD_FROM_PTR(vmemh);
- size_t old_len = MEM_lockfree_allocN_len(vmemh);
-
- if (LIKELY(!MEMHEAD_IS_ALIGNED(memh))) {
- newp = MEM_lockfree_mallocN(len, "recalloc");
- }
- else {
- MemHeadAligned *memh_aligned = MEMHEAD_ALIGNED_FROM_PTR(vmemh);
- newp = MEM_lockfree_mallocN_aligned(
- len,
- (size_t)memh_aligned->alignment,
- "recalloc");
- }
-
- if (newp) {
- if (len < old_len) {
- /* shrink */
- memcpy(newp, vmemh, len);
- }
- else {
- memcpy(newp, vmemh, old_len);
-
- if (len > old_len) {
- /* grow */
- /* zero new bytes */
- memset(((char *)newp) + old_len, 0, len - old_len);
- }
- }
- }
-
- MEM_lockfree_freeN(vmemh);
- }
- else {
- newp = MEM_lockfree_callocN(len, str);
- }
-
- return newp;
+ void *newp = NULL;
+
+ if (vmemh) {
+ MemHead *memh = MEMHEAD_FROM_PTR(vmemh);
+ size_t old_len = MEM_lockfree_allocN_len(vmemh);
+
+ if (LIKELY(!MEMHEAD_IS_ALIGNED(memh))) {
+ newp = MEM_lockfree_mallocN(len, "recalloc");
+ }
+ else {
+ MemHeadAligned *memh_aligned = MEMHEAD_ALIGNED_FROM_PTR(vmemh);
+ newp = MEM_lockfree_mallocN_aligned(len, (size_t)memh_aligned->alignment, "recalloc");
+ }
+
+ if (newp) {
+ if (len < old_len) {
+ /* shrink */
+ memcpy(newp, vmemh, len);
+ }
+ else {
+ memcpy(newp, vmemh, old_len);
+
+ if (len > old_len) {
+ /* grow */
+ /* zero new bytes */
+ memset(((char *)newp) + old_len, 0, len - old_len);
+ }
+ }
+ }
+
+ MEM_lockfree_freeN(vmemh);
+ }
+ else {
+ newp = MEM_lockfree_callocN(len, str);
+ }
+
+ return newp;
}
void *MEM_lockfree_callocN(size_t len, const char *str)
{
- MemHead *memh;
+ MemHead *memh;
- len = SIZET_ALIGN_4(len);
+ len = SIZET_ALIGN_4(len);
- memh = (MemHead *)calloc(1, len + sizeof(MemHead));
+ memh = (MemHead *)calloc(1, len + sizeof(MemHead));
- if (LIKELY(memh)) {
- memh->len = len;
- atomic_add_and_fetch_u(&totblock, 1);
- atomic_add_and_fetch_z(&mem_in_use, len);
- update_maximum(&peak_mem, mem_in_use);
+ if (LIKELY(memh)) {
+ memh->len = len;
+ atomic_add_and_fetch_u(&totblock, 1);
+ atomic_add_and_fetch_z(&mem_in_use, len);
+ update_maximum(&peak_mem, mem_in_use);
- return PTR_FROM_MEMHEAD(memh);
- }
- print_error("Calloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
- SIZET_ARG(len), str, (unsigned int) mem_in_use);
- return NULL;
+ return PTR_FROM_MEMHEAD(memh);
+ }
+ print_error("Calloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len),
+ str,
+ (unsigned int)mem_in_use);
+ return NULL;
}
void *MEM_lockfree_calloc_arrayN(size_t len, size_t size, const char *str)
{
- size_t total_size;
- if (UNLIKELY(!MEM_size_safe_multiply(len, size, &total_size))) {
- print_error("Calloc array aborted due to integer overflow: "
- "len=" SIZET_FORMAT "x" SIZET_FORMAT " in %s, total %u\n",
- SIZET_ARG(len), SIZET_ARG(size), str,
- (unsigned int) mem_in_use);
- abort();
- return NULL;
- }
-
- return MEM_lockfree_callocN(total_size, str);
+ size_t total_size;
+ if (UNLIKELY(!MEM_size_safe_multiply(len, size, &total_size))) {
+ print_error(
+ "Calloc array aborted due to integer overflow: "
+ "len=" SIZET_FORMAT "x" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len),
+ SIZET_ARG(size),
+ str,
+ (unsigned int)mem_in_use);
+ abort();
+ return NULL;
+ }
+
+ return MEM_lockfree_callocN(total_size, str);
}
void *MEM_lockfree_mallocN(size_t len, const char *str)
{
- MemHead *memh;
+ MemHead *memh;
- len = SIZET_ALIGN_4(len);
+ len = SIZET_ALIGN_4(len);
- memh = (MemHead *)malloc(len + sizeof(MemHead));
+ memh = (MemHead *)malloc(len + sizeof(MemHead));
- if (LIKELY(memh)) {
- if (UNLIKELY(malloc_debug_memset && len)) {
- memset(memh + 1, 255, len);
- }
+ if (LIKELY(memh)) {
+ if (UNLIKELY(malloc_debug_memset && len)) {
+ memset(memh + 1, 255, len);
+ }
- memh->len = len;
- atomic_add_and_fetch_u(&totblock, 1);
- atomic_add_and_fetch_z(&mem_in_use, len);
- update_maximum(&peak_mem, mem_in_use);
+ memh->len = len;
+ atomic_add_and_fetch_u(&totblock, 1);
+ atomic_add_and_fetch_z(&mem_in_use, len);
+ update_maximum(&peak_mem, mem_in_use);
- return PTR_FROM_MEMHEAD(memh);
- }
- print_error("Malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
- SIZET_ARG(len), str, (unsigned int) mem_in_use);
- return NULL;
+ return PTR_FROM_MEMHEAD(memh);
+ }
+ print_error("Malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len),
+ str,
+ (unsigned int)mem_in_use);
+ return NULL;
}
void *MEM_lockfree_malloc_arrayN(size_t len, size_t size, const char *str)
{
- size_t total_size;
- if (UNLIKELY(!MEM_size_safe_multiply(len, size, &total_size))) {
- print_error("Malloc array aborted due to integer overflow: "
- "len=" SIZET_FORMAT "x" SIZET_FORMAT " in %s, total %u\n",
- SIZET_ARG(len), SIZET_ARG(size), str,
- (unsigned int) mem_in_use);
- abort();
- return NULL;
- }
-
- return MEM_lockfree_mallocN(total_size, str);
+ size_t total_size;
+ if (UNLIKELY(!MEM_size_safe_multiply(len, size, &total_size))) {
+ print_error(
+ "Malloc array aborted due to integer overflow: "
+ "len=" SIZET_FORMAT "x" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len),
+ SIZET_ARG(size),
+ str,
+ (unsigned int)mem_in_use);
+ abort();
+ return NULL;
+ }
+
+ return MEM_lockfree_mallocN(total_size, str);
}
void *MEM_lockfree_mallocN_aligned(size_t len, size_t alignment, const char *str)
{
- MemHeadAligned *memh;
-
- /* It's possible that MemHead's size is not properly aligned,
- * do extra padding to deal with this.
- *
- * We only support small alignments which fits into short in
- * order to save some bits in MemHead structure.
- */
- size_t extra_padding = MEMHEAD_ALIGN_PADDING(alignment);
-
- /* Huge alignment values doesn't make sense and they
- * wouldn't fit into 'short' used in the MemHead.
- */
- assert(alignment < 1024);
-
- /* We only support alignment to a power of two. */
- assert(IS_POW2(alignment));
-
- len = SIZET_ALIGN_4(len);
-
- memh = (MemHeadAligned *)aligned_malloc(
- len + extra_padding + sizeof(MemHeadAligned), alignment);
-
- if (LIKELY(memh)) {
- /* We keep padding in the beginning of MemHead,
- * this way it's always possible to get MemHead
- * from the data pointer.
- */
- memh = (MemHeadAligned *)((char *)memh + extra_padding);
-
- if (UNLIKELY(malloc_debug_memset && len)) {
- memset(memh + 1, 255, len);
- }
-
- memh->len = len | (size_t) MEMHEAD_ALIGN_FLAG;
- memh->alignment = (short) alignment;
- atomic_add_and_fetch_u(&totblock, 1);
- atomic_add_and_fetch_z(&mem_in_use, len);
- update_maximum(&peak_mem, mem_in_use);
-
- return PTR_FROM_MEMHEAD(memh);
- }
- print_error("Malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
- SIZET_ARG(len), str, (unsigned int) mem_in_use);
- return NULL;
+ MemHeadAligned *memh;
+
+ /* It's possible that MemHead's size is not properly aligned,
+ * do extra padding to deal with this.
+ *
+ * We only support small alignments which fits into short in
+ * order to save some bits in MemHead structure.
+ */
+ size_t extra_padding = MEMHEAD_ALIGN_PADDING(alignment);
+
+ /* Huge alignment values doesn't make sense and they
+ * wouldn't fit into 'short' used in the MemHead.
+ */
+ assert(alignment < 1024);
+
+ /* We only support alignment to a power of two. */
+ assert(IS_POW2(alignment));
+
+ len = SIZET_ALIGN_4(len);
+
+ memh = (MemHeadAligned *)aligned_malloc(len + extra_padding + sizeof(MemHeadAligned), alignment);
+
+ if (LIKELY(memh)) {
+ /* We keep padding in the beginning of MemHead,
+ * this way it's always possible to get MemHead
+ * from the data pointer.
+ */
+ memh = (MemHeadAligned *)((char *)memh + extra_padding);
+
+ if (UNLIKELY(malloc_debug_memset && len)) {
+ memset(memh + 1, 255, len);
+ }
+
+ memh->len = len | (size_t)MEMHEAD_ALIGN_FLAG;
+ memh->alignment = (short)alignment;
+ atomic_add_and_fetch_u(&totblock, 1);
+ atomic_add_and_fetch_z(&mem_in_use, len);
+ update_maximum(&peak_mem, mem_in_use);
+
+ return PTR_FROM_MEMHEAD(memh);
+ }
+ print_error("Malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len),
+ str,
+ (unsigned int)mem_in_use);
+ return NULL;
}
void *MEM_lockfree_mapallocN(size_t len, const char *str)
{
- MemHead *memh;
+ MemHead *memh;
- /* on 64 bit, simply use calloc instead, as mmap does not support
- * allocating > 4 GB on Windows. the only reason mapalloc exists
- * is to get around address space limitations in 32 bit OSes. */
- if (sizeof(void *) >= 8)
- return MEM_lockfree_callocN(len, str);
+ /* on 64 bit, simply use calloc instead, as mmap does not support
+ * allocating > 4 GB on Windows. the only reason mapalloc exists
+ * is to get around address space limitations in 32 bit OSes. */
+ if (sizeof(void *) >= 8)
+ return MEM_lockfree_callocN(len, str);
- len = SIZET_ALIGN_4(len);
+ len = SIZET_ALIGN_4(len);
#if defined(WIN32)
- /* our windows mmap implementation is not thread safe */
- mem_lock_thread();
+ /* our windows mmap implementation is not thread safe */
+ mem_lock_thread();
#endif
- memh = mmap(NULL, len + sizeof(MemHead),
- PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
+ memh = mmap(NULL, len + sizeof(MemHead), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
#if defined(WIN32)
- mem_unlock_thread();
+ mem_unlock_thread();
#endif
- if (memh != (MemHead *)-1) {
- memh->len = len | (size_t) MEMHEAD_MMAP_FLAG;
- atomic_add_and_fetch_u(&totblock, 1);
- atomic_add_and_fetch_z(&mem_in_use, len);
- atomic_add_and_fetch_z(&mmap_in_use, len);
-
- update_maximum(&peak_mem, mem_in_use);
- update_maximum(&peak_mem, mmap_in_use);
-
- return PTR_FROM_MEMHEAD(memh);
- }
- print_error("Mapalloc returns null, fallback to regular malloc: "
- "len=" SIZET_FORMAT " in %s, total %u\n",
- SIZET_ARG(len), str, (unsigned int) mmap_in_use);
- return MEM_lockfree_callocN(len, str);
+ if (memh != (MemHead *)-1) {
+ memh->len = len | (size_t)MEMHEAD_MMAP_FLAG;
+ atomic_add_and_fetch_u(&totblock, 1);
+ atomic_add_and_fetch_z(&mem_in_use, len);
+ atomic_add_and_fetch_z(&mmap_in_use, len);
+
+ update_maximum(&peak_mem, mem_in_use);
+ update_maximum(&peak_mem, mmap_in_use);
+
+ return PTR_FROM_MEMHEAD(memh);
+ }
+ print_error(
+ "Mapalloc returns null, fallback to regular malloc: "
+ "len=" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len),
+ str,
+ (unsigned int)mmap_in_use);
+ return MEM_lockfree_callocN(len, str);
}
void MEM_lockfree_printmemlist_pydict(void)
@@ -440,78 +446,78 @@ void MEM_lockfree_printmemlist(void)
/* unused */
void MEM_lockfree_callbackmemlist(void (*func)(void *))
{
- (void) func; /* Ignored. */
+ (void)func; /* Ignored. */
}
void MEM_lockfree_printmemlist_stats(void)
{
- printf("\ntotal memory len: %.3f MB\n",
- (double)mem_in_use / (double)(1024 * 1024));
- printf("peak memory len: %.3f MB\n",
- (double)peak_mem / (double)(1024 * 1024));
- printf("\nFor more detailed per-block statistics run Blender with memory debugging command line argument.\n");
+ printf("\ntotal memory len: %.3f MB\n", (double)mem_in_use / (double)(1024 * 1024));
+ printf("peak memory len: %.3f MB\n", (double)peak_mem / (double)(1024 * 1024));
+ printf(
+ "\nFor more detailed per-block statistics run Blender with memory debugging command line "
+ "argument.\n");
#ifdef HAVE_MALLOC_STATS
- printf("System Statistics:\n");
- malloc_stats();
+ printf("System Statistics:\n");
+ malloc_stats();
#endif
}
void MEM_lockfree_set_error_callback(void (*func)(const char *))
{
- error_callback = func;
+ error_callback = func;
}
bool MEM_lockfree_consistency_check(void)
{
- return true;
+ return true;
}
void MEM_lockfree_set_lock_callback(void (*lock)(void), void (*unlock)(void))
{
- thread_lock_callback = lock;
- thread_unlock_callback = unlock;
+ thread_lock_callback = lock;
+ thread_unlock_callback = unlock;
}
void MEM_lockfree_set_memory_debug(void)
{
- malloc_debug_memset = true;
+ malloc_debug_memset = true;
}
size_t MEM_lockfree_get_memory_in_use(void)
{
- return mem_in_use;
+ return mem_in_use;
}
size_t MEM_lockfree_get_mapped_memory_in_use(void)
{
- return mmap_in_use;
+ return mmap_in_use;
}
unsigned int MEM_lockfree_get_memory_blocks_in_use(void)
{
- return totblock;
+ return totblock;
}
/* dummy */
void MEM_lockfree_reset_peak_memory(void)
{
- peak_mem = mem_in_use;
+ peak_mem = mem_in_use;
}
size_t MEM_lockfree_get_peak_memory(void)
{
- return peak_mem;
+ return peak_mem;
}
#ifndef NDEBUG
const char *MEM_lockfree_name_ptr(void *vmemh)
{
- if (vmemh) {
- return "unknown block name ptr";
- }
- else {
- return "MEM_lockfree_name_ptr(NULL)";
- }
+ if (vmemh) {
+ return "unknown block name ptr";
+ }
+ else {
+ return "MEM_lockfree_name_ptr(NULL)";
+ }
}
-#endif /* NDEBUG */
+#endif /* NDEBUG */
diff --git a/intern/guardedalloc/intern/mmap_win.c b/intern/guardedalloc/intern/mmap_win.c
index 93b0370a011..d5488351700 100644
--- a/intern/guardedalloc/intern/mmap_win.c
+++ b/intern/guardedalloc/intern/mmap_win.c
@@ -23,43 +23,43 @@
#ifdef WIN32
-#include <windows.h>
-#include <errno.h>
-#include <io.h>
-#include <sys/types.h>
-#include <stdio.h>
+# include <windows.h>
+# include <errno.h>
+# include <io.h>
+# include <sys/types.h>
+# include <stdio.h>
-#include "mmap_win.h"
+# include "mmap_win.h"
-#ifndef FILE_MAP_EXECUTE
+# ifndef FILE_MAP_EXECUTE
//not defined in earlier versions of the Platform SDK (before February 2003)
-#define FILE_MAP_EXECUTE 0x0020
-#endif
+# define FILE_MAP_EXECUTE 0x0020
+# endif
/* copied from BLI_utildefines.h, ugh */
-#ifdef __GNUC__
-# define UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
-#else
-# define UNUSED(x) x
-#endif
+# ifdef __GNUC__
+# define UNUSED(x) UNUSED_##x __attribute__((__unused__))
+# else
+# define UNUSED(x) x
+# endif
/* --------------------------------------------------------------------- */
/* local storage definitions */
/* --------------------------------------------------------------------- */
/* all memory mapped chunks are put in linked lists */
typedef struct mmapLink {
- struct mmapLink *next, *prev;
+ struct mmapLink *next, *prev;
} mmapLink;
typedef struct mmapListBase {
- void *first, *last;
+ void *first, *last;
} mmapListBase;
typedef struct MemMap {
- struct MemMap *next, *prev;
- void *mmap;
- HANDLE fhandle;
- HANDLE maphandle;
+ struct MemMap *next, *prev;
+ void *mmap;
+ HANDLE fhandle;
+ HANDLE maphandle;
} MemMap;
/* --------------------------------------------------------------------- */
@@ -79,7 +79,6 @@ static int mmap_get_access_flags(int flags);
volatile static struct mmapListBase _mmapbase;
volatile static struct mmapListBase *mmapbase = &_mmapbase;
-
/* --------------------------------------------------------------------- */
/* implementation */
/* --------------------------------------------------------------------- */
@@ -87,84 +86,89 @@ volatile static struct mmapListBase *mmapbase = &_mmapbase;
/* mmap for windows */
void *mmap(void *UNUSED(start), size_t len, int prot, int flags, int fd, off_t offset)
{
- HANDLE fhandle = INVALID_HANDLE_VALUE;
- HANDLE maphandle;
- int prot_flags = mmap_get_prot_flags(prot);
- int access_flags = mmap_get_access_flags(prot);
- MemMap *mm = NULL;
- void *ptr = NULL;
-
- if (flags & MAP_FIXED) {
- return MAP_FAILED;
- }
-
-#if 0
- if ( fd == -1 ) {
- _set_errno( EBADF );
- return MAP_FAILED;
- }
-#endif
-
- if (fd != -1) {
- fhandle = (HANDLE) _get_osfhandle(fd);
- }
- if (fhandle == INVALID_HANDLE_VALUE) {
- if (!(flags & MAP_ANONYMOUS)) {
- errno = EBADF;
- return MAP_FAILED;
- }
- }
- else {
- if (!DuplicateHandle(GetCurrentProcess(), fhandle, GetCurrentProcess(),
- &fhandle, 0, FALSE, DUPLICATE_SAME_ACCESS) ) {
- return MAP_FAILED;
- }
- }
-
- /* note len is passed to a 32 bit DWORD, so can't be > 4 GB */
- maphandle = CreateFileMapping(fhandle, NULL, prot_flags, 0, len, NULL);
- if (maphandle == 0) {
- errno = EBADF;
- return MAP_FAILED;
- }
-
- ptr = MapViewOfFile(maphandle, access_flags, 0, offset, 0);
- if (ptr == NULL) {
- DWORD dwLastErr = GetLastError();
- if (dwLastErr == ERROR_MAPPED_ALIGNMENT)
- errno = EINVAL;
- else
- errno = EACCES;
- CloseHandle(maphandle);
- return MAP_FAILED;
- }
-
- mm = (MemMap *)malloc(sizeof(MemMap));
- if (!mm) {
- errno = ENOMEM;
- }
- mm->fhandle = fhandle;
- mm->maphandle = maphandle;
- mm->mmap = ptr;
- mmap_addtail(mmapbase, mm);
-
- return ptr;
+ HANDLE fhandle = INVALID_HANDLE_VALUE;
+ HANDLE maphandle;
+ int prot_flags = mmap_get_prot_flags(prot);
+ int access_flags = mmap_get_access_flags(prot);
+ MemMap *mm = NULL;
+ void *ptr = NULL;
+
+ if (flags & MAP_FIXED) {
+ return MAP_FAILED;
+ }
+
+# if 0
+ if ( fd == -1 ) {
+ _set_errno( EBADF );
+ return MAP_FAILED;
+ }
+# endif
+
+ if (fd != -1) {
+ fhandle = (HANDLE)_get_osfhandle(fd);
+ }
+ if (fhandle == INVALID_HANDLE_VALUE) {
+ if (!(flags & MAP_ANONYMOUS)) {
+ errno = EBADF;
+ return MAP_FAILED;
+ }
+ }
+ else {
+ if (!DuplicateHandle(GetCurrentProcess(),
+ fhandle,
+ GetCurrentProcess(),
+ &fhandle,
+ 0,
+ FALSE,
+ DUPLICATE_SAME_ACCESS)) {
+ return MAP_FAILED;
+ }
+ }
+
+ /* note len is passed to a 32 bit DWORD, so can't be > 4 GB */
+ maphandle = CreateFileMapping(fhandle, NULL, prot_flags, 0, len, NULL);
+ if (maphandle == 0) {
+ errno = EBADF;
+ return MAP_FAILED;
+ }
+
+ ptr = MapViewOfFile(maphandle, access_flags, 0, offset, 0);
+ if (ptr == NULL) {
+ DWORD dwLastErr = GetLastError();
+ if (dwLastErr == ERROR_MAPPED_ALIGNMENT)
+ errno = EINVAL;
+ else
+ errno = EACCES;
+ CloseHandle(maphandle);
+ return MAP_FAILED;
+ }
+
+ mm = (MemMap *)malloc(sizeof(MemMap));
+ if (!mm) {
+ errno = ENOMEM;
+ }
+ mm->fhandle = fhandle;
+ mm->maphandle = maphandle;
+ mm->mmap = ptr;
+ mmap_addtail(mmapbase, mm);
+
+ return ptr;
}
/* munmap for windows */
intptr_t munmap(void *ptr, size_t UNUSED(size))
{
- MemMap *mm = mmap_findlink(mmapbase, ptr);
- if (!mm) {
- errno = EINVAL;
- return -1;
- }
- UnmapViewOfFile(mm->mmap);
- CloseHandle(mm->maphandle);
- CloseHandle(mm->fhandle);
- mmap_remlink(mmapbase, mm);
- free(mm);
- return 0;
+ MemMap *mm = mmap_findlink(mmapbase, ptr);
+ if (!mm) {
+ errno = EINVAL;
+ return -1;
+ }
+ UnmapViewOfFile(mm->mmap);
+ CloseHandle(mm->maphandle);
+ CloseHandle(mm->fhandle);
+ mmap_remlink(mmapbase, mm);
+ free(mm);
+ return 0;
}
/* --------------------------------------------------------------------- */
@@ -173,90 +177,102 @@ intptr_t munmap(void *ptr, size_t UNUSED(size))
static void mmap_addtail(volatile mmapListBase *listbase, void *vlink)
{
- struct mmapLink *link = vlink;
+ struct mmapLink *link = vlink;
- if (link == NULL) return;
- if (listbase == NULL) return;
+ if (link == NULL)
+ return;
+ if (listbase == NULL)
+ return;
- link->next = 0;
- link->prev = listbase->last;
+ link->next = 0;
+ link->prev = listbase->last;
- if (listbase->last) ((struct mmapLink *)listbase->last)->next = link;
- if (listbase->first == NULL) listbase->first = link;
- listbase->last = link;
+ if (listbase->last)
+ ((struct mmapLink *)listbase->last)->next = link;
+ if (listbase->first == NULL)
+ listbase->first = link;
+ listbase->last = link;
}
static void mmap_remlink(volatile mmapListBase *listbase, void *vlink)
{
- struct mmapLink *link = vlink;
-
- if (link == NULL) return;
- if (listbase == NULL) return;
-
- if (link->next) link->next->prev = link->prev;
- if (link->prev) link->prev->next = link->next;
-
- if (listbase->last == link) listbase->last = link->prev;
- if (listbase->first == link) listbase->first = link->next;
+ struct mmapLink *link = vlink;
+
+ if (link == NULL)
+ return;
+ if (listbase == NULL)
+ return;
+
+ if (link->next)
+ link->next->prev = link->prev;
+ if (link->prev)
+ link->prev->next = link->next;
+
+ if (listbase->last == link)
+ listbase->last = link->prev;
+ if (listbase->first == link)
+ listbase->first = link->next;
}
static void *mmap_findlink(volatile mmapListBase *listbase, void *ptr)
{
- MemMap *mm;
-
- if (ptr == NULL) return NULL;
- if (listbase == NULL) return NULL;
-
- mm = (MemMap *)listbase->first;
- while (mm) {
- if (mm->mmap == ptr) {
- return mm;
- }
- mm = mm->next;
- }
- return NULL;
+ MemMap *mm;
+
+ if (ptr == NULL)
+ return NULL;
+ if (listbase == NULL)
+ return NULL;
+
+ mm = (MemMap *)listbase->first;
+ while (mm) {
+ if (mm->mmap == ptr) {
+ return mm;
+ }
+ mm = mm->next;
+ }
+ return NULL;
}
static int mmap_get_prot_flags(int flags)
{
- int prot = PAGE_NOACCESS;
-
- if ( (flags & PROT_READ) == PROT_READ) {
- if ( (flags & PROT_WRITE) == PROT_WRITE) {
- prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
- }
- else {
- prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READ : PAGE_READONLY;
- }
- }
- else if ( (flags & PROT_WRITE) == PROT_WRITE) {
- prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READ : PAGE_WRITECOPY;
- }
- else if ( (flags & PROT_EXEC) == PROT_EXEC) {
- prot = PAGE_EXECUTE_READ;
- }
- return prot;
+ int prot = PAGE_NOACCESS;
+
+ if ((flags & PROT_READ) == PROT_READ) {
+ if ((flags & PROT_WRITE) == PROT_WRITE) {
+ prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
+ }
+ else {
+ prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READ : PAGE_READONLY;
+ }
+ }
+ else if ((flags & PROT_WRITE) == PROT_WRITE) {
+ prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READ : PAGE_WRITECOPY;
+ }
+ else if ((flags & PROT_EXEC) == PROT_EXEC) {
+ prot = PAGE_EXECUTE_READ;
+ }
+ return prot;
}
static int mmap_get_access_flags(int flags)
{
- int access = 0;
-
- if ( (flags & PROT_READ) == PROT_READ) {
- if ( (flags & PROT_WRITE) == PROT_WRITE) {
- access = FILE_MAP_WRITE;
- }
- else {
- access = (flags & PROT_EXEC) ? FILE_MAP_EXECUTE : FILE_MAP_READ;
- }
- }
- else if ( (flags & PROT_WRITE) == PROT_WRITE) {
- access = FILE_MAP_COPY;
- }
- else if ( (flags & PROT_EXEC) == PROT_EXEC) {
- access = FILE_MAP_EXECUTE;
- }
- return access;
+ int access = 0;
+
+ if ((flags & PROT_READ) == PROT_READ) {
+ if ((flags & PROT_WRITE) == PROT_WRITE) {
+ access = FILE_MAP_WRITE;
+ }
+ else {
+ access = (flags & PROT_EXEC) ? FILE_MAP_EXECUTE : FILE_MAP_READ;
+ }
+ }
+ else if ((flags & PROT_WRITE) == PROT_WRITE) {
+ access = FILE_MAP_COPY;
+ }
+ else if ((flags & PROT_EXEC) == PROT_EXEC) {
+ access = FILE_MAP_EXECUTE;
+ }
+ return access;
}
-#endif // WIN32
+#endif // WIN32
diff --git a/intern/guardedalloc/test/simpletest/memtest.c b/intern/guardedalloc/test/simpletest/memtest.c
index 2ab3653b435..576e502b72e 100644
--- a/intern/guardedalloc/test/simpletest/memtest.c
+++ b/intern/guardedalloc/test/simpletest/memtest.c
@@ -36,118 +36,122 @@
static void mem_error_cb(const char *errorStr)
{
- fprintf(stderr, "%s", errorStr);
- fflush(stderr);
+ fprintf(stderr, "%s", errorStr);
+ fflush(stderr);
}
int main(int argc, char *argv[])
{
- int verbose = 0;
- int error_status = 0;
- int retval = 0;
- int *ip;
-
- void *p[NUM_BLOCKS];
- int i = 0;
-
- /* ----------------------------------------------------------------- */
- switch (argc) {
- case 2:
- verbose = atoi(argv[1]);
- if (verbose < 0) verbose = 0;
- break;
- case 1:
- default:
- verbose = 0;
- }
- if (verbose) {
- fprintf(stderr,"\n*** Simple memory test\n|\n");
- }
-
- /* ----------------------------------------------------------------- */
- /* Round one, do a normal allocation, and free the blocks again. */
- /* ----------------------------------------------------------------- */
- /* flush mem lib output to stderr */
- MEM_set_error_callback(mem_error_cb);
-
- for (i = 0; i < NUM_BLOCKS; i++) {
- int blocksize = 10000;
- char tagstring[1000];
- if (verbose > 1) printf("|--* Allocating block %d\n", i);
- sprintf(tagstring,"Memblock no. %d : ", i);
- p[i]= MEM_callocN(blocksize, strdup(tagstring));
- }
-
- /* report on that */
- if (verbose > 1) MEM_printmemlist();
-
- /* memory is there: test it */
- error_status = MEM_consistency_check();
-
- if (verbose) {
- if (error_status) {
- fprintf(stderr, "|--* Memory test FAILED\n|\n");
- }
- else {
- fprintf(stderr, "|--* Memory tested as good (as it should be)\n|\n");
- }
- }
-
- for (i = 0; i < NUM_BLOCKS; i++) {
- MEM_freeN(p[i]);
- }
-
- /* ----------------------------------------------------------------- */
- /* Round two, do a normal allocation, and corrupt some blocks. */
- /* ----------------------------------------------------------------- */
- /* switch off, because it will complain about some things. */
- MEM_set_error_callback(NULL);
-
- for (i = 0; i < NUM_BLOCKS; i++) {
- int blocksize = 10000;
- char tagstring[1000];
- if (verbose > 1) printf("|--* Allocating block %d\n", i);
- sprintf(tagstring,"Memblock no. %d : ", i);
- p[i]= MEM_callocN(blocksize, strdup(tagstring));
- }
-
- /* now corrupt a few blocks...*/
- ip = (int*) p[5] - 50;
- for (i = 0; i< 1000; i++,ip++) *ip = i+1;
- ip = (int*) p[6];
- *(ip+10005) = 0;
-
- retval = MEM_consistency_check();
-
- /* the test should have failed */
- error_status |= !retval;
- if (verbose) {
- if (retval) {
- fprintf(stderr, "|--* Memory test failed (as it should be)\n");
- }
- else {
- fprintf(stderr, "|--* Memory test FAILED to find corrupted blocks \n");
- }
- }
-
- for (i = 0; i < NUM_BLOCKS; i++) {
- MEM_freeN(p[i]);
- }
-
-
- if (verbose && error_status) {
- fprintf(stderr,"|--* Memory was corrupted\n");
- }
- /* ----------------------------------------------------------------- */
- if (verbose) {
- if (error_status) {
- fprintf(stderr,"|\n|--* Errors were detected\n");
- }
- else {
- fprintf(stderr,"|\n|--* Test exited succesfully\n");
- }
-
- fprintf(stderr,"|\n*** Finished test\n\n");
- }
- return error_status;
+ int verbose = 0;
+ int error_status = 0;
+ int retval = 0;
+ int *ip;
+
+ void *p[NUM_BLOCKS];
+ int i = 0;
+
+ /* ----------------------------------------------------------------- */
+ switch (argc) {
+ case 2:
+ verbose = atoi(argv[1]);
+ if (verbose < 0)
+ verbose = 0;
+ break;
+ case 1:
+ default:
+ verbose = 0;
+ }
+ if (verbose) {
+ fprintf(stderr, "\n*** Simple memory test\n|\n");
+ }
+
+ /* ----------------------------------------------------------------- */
+ /* Round one, do a normal allocation, and free the blocks again. */
+ /* ----------------------------------------------------------------- */
+ /* flush mem lib output to stderr */
+ MEM_set_error_callback(mem_error_cb);
+
+ for (i = 0; i < NUM_BLOCKS; i++) {
+ int blocksize = 10000;
+ char tagstring[1000];
+ if (verbose > 1)
+ printf("|--* Allocating block %d\n", i);
+ sprintf(tagstring, "Memblock no. %d : ", i);
+ p[i] = MEM_callocN(blocksize, strdup(tagstring));
+ }
+
+ /* report on that */
+ if (verbose > 1)
+ MEM_printmemlist();
+
+ /* memory is there: test it */
+ error_status = MEM_consistency_check();
+
+ if (verbose) {
+ if (error_status) {
+ fprintf(stderr, "|--* Memory test FAILED\n|\n");
+ }
+ else {
+ fprintf(stderr, "|--* Memory tested as good (as it should be)\n|\n");
+ }
+ }
+
+ for (i = 0; i < NUM_BLOCKS; i++) {
+ MEM_freeN(p[i]);
+ }
+
+ /* ----------------------------------------------------------------- */
+ /* Round two, do a normal allocation, and corrupt some blocks. */
+ /* ----------------------------------------------------------------- */
+ /* switch off, because it will complain about some things. */
+ MEM_set_error_callback(NULL);
+
+ for (i = 0; i < NUM_BLOCKS; i++) {
+ int blocksize = 10000;
+ char tagstring[1000];
+ if (verbose > 1)
+ printf("|--* Allocating block %d\n", i);
+ sprintf(tagstring, "Memblock no. %d : ", i);
+ p[i] = MEM_callocN(blocksize, strdup(tagstring));
+ }
+
+ /* now corrupt a few blocks...*/
+ ip = (int *)p[5] - 50;
+ for (i = 0; i < 1000; i++, ip++)
+ *ip = i + 1;
+ ip = (int *)p[6];
+ *(ip + 10005) = 0;
+
+ retval = MEM_consistency_check();
+
+ /* the test should have failed */
+ error_status |= !retval;
+ if (verbose) {
+ if (retval) {
+ fprintf(stderr, "|--* Memory test failed (as it should be)\n");
+ }
+ else {
+ fprintf(stderr, "|--* Memory test FAILED to find corrupted blocks \n");
+ }
+ }
+
+ for (i = 0; i < NUM_BLOCKS; i++) {
+ MEM_freeN(p[i]);
+ }
+
+ if (verbose && error_status) {
+ fprintf(stderr, "|--* Memory was corrupted\n");
+ }
+ /* ----------------------------------------------------------------- */
+ if (verbose) {
+ if (error_status) {
+ fprintf(stderr, "|\n|--* Errors were detected\n");
+ }
+ else {
+ fprintf(stderr, "|\n|--* Test exited succesfully\n");
+ }
+
+ fprintf(stderr, "|\n*** Finished test\n\n");
+ }
+ return error_status;
}