[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [60658] trunk/blender: Lock-free memory allocator

Sergey Sharybin sergey.vfx at gmail.com
Thu Oct 10 13:58:02 CEST 2013


Revision: 60658
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=60658
Author:   nazgul
Date:     2013-10-10 11:58:01 +0000 (Thu, 10 Oct 2013)
Log Message:
-----------
Lock-free memory allocator

Release builds will now use lock-free allocator by
default without any internal locks happening.

MemHead is also reduces to as minimum as it's possible.
It still need to be size_t stored in a MemHead in order
to make us keep track on memory we're requesting from
the system, not memory which system is allocating. This
is probably also faster than using a malloc's usable
size function.

Lock-free guarded allocator will say you whether all
the blocks were freed, but wouldn't give you a list
of unfreed blocks list. To have such a list use a
--debug or --debug-memory command line arguments.

Debug builds does have the same behavior as release
builds. This is so tools like valgrind are not
screwed up by guarded allocator as they're currently
are.

--
svn merge -r59941:59942 -r60072:60073 -r60093:60094 \
          -r60095:60096 ^/branches/soc-2013-depsgraph_mt

Revision Links:
--------------
    http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=59941
    http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=60072
    http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=60093
    http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=60095

Modified Paths:
--------------
    trunk/blender/CMakeLists.txt
    trunk/blender/intern/guardedalloc/CMakeLists.txt
    trunk/blender/intern/guardedalloc/MEM_guardedalloc.h
    trunk/blender/intern/guardedalloc/SConscript
    trunk/blender/intern/guardedalloc/intern/mallocn.c
    trunk/blender/source/blender/makesdna/intern/CMakeLists.txt
    trunk/blender/source/blender/makesdna/intern/SConscript
    trunk/blender/source/blender/makesrna/intern/CMakeLists.txt
    trunk/blender/source/blender/makesrna/intern/SConscript
    trunk/blender/source/creator/creator.c

Added Paths:
-----------
    trunk/blender/intern/guardedalloc/intern/mallocn_guarded_impl.c
    trunk/blender/intern/guardedalloc/intern/mallocn_intern.h
    trunk/blender/intern/guardedalloc/intern/mallocn_lockfree_impl.c

Property Changed:
----------------
    trunk/blender/
    trunk/blender/source/blender/editors/interface/interface.c
    trunk/blender/source/blender/editors/space_outliner/


Property changes on: trunk/blender
___________________________________________________________________
Modified: svn:mergeinfo
   - /branches/ge_dev:58091-58422
/branches/ge_harmony:42255,42279-42282,42286,42302,42338,42349,42616,42620,42698-42699,42739,42753,42773-42774,42832,44568,44597-44598,44793-44794
/branches/soc-2011-cucumber:37517,38166-38167,38177,38179-38180,38187,38242,38384,38387,38403-38404,38407,38968,38970,38973,39045,40845,42997-42998,43439
/branches/soc-2011-tomato:42376,42378-42379,42383,42385,42395,42397-42400,42407,42411,42418,42443-42444,42446,42467,42472,42486,42650-42652,42654-42655,42709-42710,42733-42734,42801,43872,44130,44141,44147-44149,44151-44152,44229-44230,45623-45625,46037,48089,48092,48551-48552,48679,48790,48792-48793,49076,49087,49292,49294,49466,49894,50052,50126,52854-52856,54573,58822,58989
/branches/soc-2013-depsgraph_mt:57516,57900,57939-57940,57945,57958-57961,58151,58155-58156,58169,58277-58279,58282-58283,58711,58787,58789,58796,59086-59087,59163,59166,59170,59181,59259-59260,60105
/branches/soc-2013-dingto:57424,57487,57507,57525,57599,57670,57918-57919,57981,58091,58245,58253,58587,58772,58774-58775,58828,58835,59032,59214,59220,59251,59601
/branches/soc-2013-rigid_body_sim:60311
/tags/blender-2.67b-release/blender:57122
   + /branches/ge_dev:58091-58422
/branches/ge_harmony:42255,42279-42282,42286,42302,42338,42349,42616,42620,42698-42699,42739,42753,42773-42774,42832,44568,44597-44598,44793-44794
/branches/soc-2011-cucumber:37517,38166-38167,38177,38179-38180,38187,38242,38384,38387,38403-38404,38407,38968,38970,38973,39045,40845,42997-42998,43439
/branches/soc-2011-tomato:42376,42378-42379,42383,42385,42395,42397-42400,42407,42411,42418,42443-42444,42446,42467,42472,42486,42650-42652,42654-42655,42709-42710,42733-42734,42801,43872,44130,44141,44147-44149,44151-44152,44229-44230,45623-45625,46037,48089,48092,48551-48552,48679,48790,48792-48793,49076,49087,49292,49294,49466,49894,50052,50126,52854-52856,54573,58822,58989
/branches/soc-2013-depsgraph_mt:57516,57900,57939-57940,57945,57958-57961,58151,58155-58156,58169,58277-58279,58282-58283,58711,58787,58789,58796,59086-59087,59163,59166,59170,59181,59259-59260,59942,60073,60094,60096,60105
/branches/soc-2013-dingto:57424,57487,57507,57525,57599,57670,57918-57919,57981,58091,58245,58253,58587,58772,58774-58775,58828,58835,59032,59214,59220,59251,59601
/branches/soc-2013-rigid_body_sim:60311
/tags/blender-2.67b-release/blender:57122

Modified: trunk/blender/CMakeLists.txt
===================================================================
--- trunk/blender/CMakeLists.txt	2013-10-10 11:33:20 UTC (rev 60657)
+++ trunk/blender/CMakeLists.txt	2013-10-10 11:58:01 UTC (rev 60658)
@@ -287,9 +287,6 @@
 option(WITH_CXX_GUARDEDALLOC "Enable GuardedAlloc for C++ memory allocation tracking (only enable for development)" OFF)
 mark_as_advanced(WITH_CXX_GUARDEDALLOC)
 
-option(WITH_GUARDEDALLOC "Enable GuardedAlloc (DISABLE AT OWN RISK!)" ON)
-mark_as_advanced(WITH_GUARDEDALLOC)
-
 option(WITH_ASSERT_ABORT "Call abort() when raising an assertion through BLI_assert()" OFF)
 mark_as_advanced(WITH_ASSERT_ABORT)
 

Modified: trunk/blender/intern/guardedalloc/CMakeLists.txt
===================================================================
--- trunk/blender/intern/guardedalloc/CMakeLists.txt	2013-10-10 11:33:20 UTC (rev 60657)
+++ trunk/blender/intern/guardedalloc/CMakeLists.txt	2013-10-10 11:58:01 UTC (rev 60658)
@@ -34,11 +34,11 @@
 
 set(SRC
 	./intern/mallocn.c
+	./intern/mallocn_guarded_impl.c
+	./intern/mallocn_lockfree_impl.c
 
 	MEM_guardedalloc.h
-
-	# include here since its a header-only
-	../atomic/atomic_ops.h
+	./intern/mallocn_intern.h
 )
 
 if(WIN32 AND NOT UNIX)
@@ -49,12 +49,6 @@
 	)
 endif()
 
-if (WITH_GUARDEDALLOC)
-	add_definitions(-DWITH_GUARDEDALLOC)
-else()
-	message(WARNING "Disabling GuardedAlloc is experemental, use at own risk!")
-endif()
-
 blender_add_lib(bf_intern_guardedalloc "${SRC}" "${INC}" "${INC_SYS}")
 
 # Override C++ alloc, optional.

Modified: trunk/blender/intern/guardedalloc/MEM_guardedalloc.h
===================================================================
--- trunk/blender/intern/guardedalloc/MEM_guardedalloc.h	2013-10-10 11:33:20 UTC (rev 60657)
+++ trunk/blender/intern/guardedalloc/MEM_guardedalloc.h	2013-10-10 11:58:01 UTC (rev 60658)
@@ -62,12 +62,10 @@
 
 #include <stdio.h>          /* needed for FILE* */
 
-/* needed for uintptr_t, exception, dont use BLI anywhere else in MEM_* */
+/* needed for uintptr_t and attributes, exception, dont use BLI anywhere else in MEM_* */
 #include "../../source/blender/blenlib/BLI_sys_types.h"
+#include "../../source/blender/blenlib/BLI_compiler_attrs.h"
 
-/* some GNU attributes are only available from GCC 4.3 */
-#define MEM_GNU_ATTRIBUTES (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 403))
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -75,57 +73,36 @@
 	/** 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.*/
-	size_t MEM_allocN_len(const void *vmemh)
-#if MEM_GNU_ATTRIBUTES
-	__attribute__((warn_unused_result))
-#endif
-	;
+	extern size_t (*MEM_allocN_len)(const void *vmemh) ATTR_WARN_UNUSED_RESULT;
 
 	/**
 	 * Release memory previously allocatred by this module. 
 	 */
-	void MEM_freeN(void *vmemh);
+	extern void (*MEM_freeN)(void *vmemh);
 
 #if 0  /* UNUSED */
 	/**
 	 * Return zero if memory is not in allocated list
 	 */
-	short MEM_testN(void *vmemh);
+	extern short (*MEM_testN)(void *vmemh);
 #endif
 
 	/**
 	 * Duplicates a block of memory, and returns a pointer to the
 	 * newly allocated block.  */
-	void *MEM_dupallocN(const void *vmemh)
-#if MEM_GNU_ATTRIBUTES
-	__attribute__((malloc))
-	__attribute__((warn_unused_result))
-#endif
-	;
+	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. */
-	void *MEM_reallocN_id(void *vmemh, size_t len, const char *str)
-#if MEM_GNU_ATTRIBUTES
-	__attribute__((malloc))
-	__attribute__((warn_unused_result))
-	__attribute__((alloc_size(2)))
-#endif
-	;
+	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
 	 */
-	void *MEM_recallocN_id(void *vmemh, size_t len, const char *str)
-#if MEM_GNU_ATTRIBUTES
-	__attribute__((malloc))
-	__attribute__((warn_unused_result))
-	__attribute__((alloc_size(2)))
-#endif
-	;
+	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__)
@@ -134,97 +111,75 @@
 	 * 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 ! */
-	void *MEM_callocN(size_t len, const char *str)
-#if MEM_GNU_ATTRIBUTES
-	__attribute__((malloc))
-	__attribute__((warn_unused_result))
-	__attribute__((nonnull(2)))
-	__attribute__((alloc_size(1)))
-#endif
-	;
+	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, with tag name str. The
 	 * name must be a static, because only a pointer to it is stored !
 	 * */
-	void *MEM_mallocN(size_t len, const char *str)
-#if MEM_GNU_ATTRIBUTES
-	__attribute__((malloc))
-	__attribute__((warn_unused_result))
-	__attribute__((nonnull(2)))
-	__attribute__((alloc_size(1)))
-#endif
-	;
+	extern void *(*MEM_mallocN)(size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
 
 	/**
 	 * Same as callocN, clears memory and uses mmap (disk cached) if supported.
 	 * Can be free'd with MEM_freeN as usual.
 	 * */
-	void *MEM_mapallocN(size_t len, const char *str)
-#if MEM_GNU_ATTRIBUTES
-	__attribute__((malloc))
-	__attribute__((warn_unused_result))
-	__attribute__((nonnull(2)))
-	__attribute__((alloc_size(1)))
-#endif
-	;
+	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 */ 
-	void MEM_printmemlist_pydict(void);
+	extern void (*MEM_printmemlist_pydict)(void);
 
 	/** Print a list of the names and sizes of all allocated memory
 	 * blocks. */ 
-	void MEM_printmemlist(void);
+	extern void (*MEM_printmemlist)(void);
 
 	/** calls the function on all allocated memory blocks. */
-	void MEM_callbackmemlist(void (*func)(void *));
+	extern void (*MEM_callbackmemlist)(void (*func)(void *));
 
 	/** Print statistics about memory usage */
-	void MEM_printmemlist_stats(void);
+	extern void (*MEM_printmemlist_stats)(void);
 	
 	/** Set the callback function for error output. */
-	void MEM_set_error_callback(void (*func)(const char *));
+	extern void (*MEM_set_error_callback)(void (*func)(const char *));
 
 	/**
 	 * Are the start/end block markers still correct ?
 	 *
 	 * @retval 0 for correct memory, 1 for corrupted memory. */
-	bool MEM_check_memory_integrity(void);
+	extern bool (*MEM_check_memory_integrity)(void);
 
 	/** Set thread locking functions for safe memory allocation from multiple
 	 * threads, pass NULL pointers to disable thread locking again. */
-	void MEM_set_lock_callback(void (*lock)(void), void (*unlock)(void));
+	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 */
-	void MEM_set_memory_debug(void);
+	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 */
-	uintptr_t MEM_get_memory_in_use(void);
+	extern uintptr_t (*MEM_get_memory_in_use)(void);
 	/** Get mapped memory usage. */
-	uintptr_t MEM_get_mapped_memory_in_use(void);

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list