From e12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 17 Apr 2019 06:17:24 +0200 Subject: ClangFormat: apply to source, most of intern Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat --- intern/guardedalloc/CMakeLists.txt | 38 +- intern/guardedalloc/MEM_guardedalloc.h | 351 ++--- intern/guardedalloc/cpp/mallocn.cpp | 23 +- intern/guardedalloc/intern/mallocn.c | 95 +- intern/guardedalloc/intern/mallocn_guarded_impl.c | 1518 ++++++++++---------- intern/guardedalloc/intern/mallocn_inline.h | 28 +- intern/guardedalloc/intern/mallocn_intern.h | 94 +- intern/guardedalloc/intern/mallocn_lockfree_impl.c | 616 ++++---- intern/guardedalloc/intern/mmap_win.c | 336 ++--- intern/guardedalloc/test/simpletest/memtest.c | 224 +-- 10 files changed, 1736 insertions(+), 1587 deletions(-) (limited to 'intern/guardedalloc') 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 /* needed for FILE* */ +#include /* 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 #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 -# include -# 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 +# include +# 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 # 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 -#include -#include -#include -#include +# include +# include +# include +# include +# include -#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; } -- cgit v1.2.3