Cleanup: remove redundant, invalid info from headers
[blender.git] / intern / guardedalloc / MEM_guardedalloc.h
index a4beea6d8d5615141f1a59f5017fa3768751ecb8..d23bab63d671b920930ea2c855dc0206daaf9bea 100644 (file)
@@ -1,7 +1,4 @@
 /*
- * $Id$
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
  *
  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
  * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
  */
 
-/** \file MEM_guardedalloc.h
- *  \ingroup MEM
+/**
+ * \file MEM_guardedalloc.h
+ * \ingroup MEM
+ *
+ * \author Copyright (C) 2001 NaN Technologies B.V.
+ * \brief Read \ref MEMPage
  *
- *  \author Copyright (C) 2001 NaN Technologies B.V.
- *  \brief Read \ref MEMPage
- */
-
-/** 
  * \page MEMPage Guarded memory(de)allocation
  *
  * \section aboutmem c-style guarded memory allocation
  *
  * There are currently no known issues with MEM. Note that there is a
  * second intern/ module with MEM_ prefix, for use in c++.
- * 
+ *
  * \subsection memdependencies Dependencies
  * - stdlib
  * - stdio
- * 
+ *
  * \subsection memdocs API Documentation
  * See \ref MEM_guardedalloc.h
  */
 
-#ifndef MEM_MALLOCN_H
-#define MEM_MALLOCN_H
-
-#ifndef LIBEXPORT
-#ifdef _WIN32
-#ifdef BLENDER_PLUGIN
-#define LIBEXPORT __declspec(dllimport)
-#else
-#define LIBEXPORT __declspec(dllexport)
-#endif
-#else
-#define LIBEXPORT
-#endif
-#endif
+#ifndef __MEM_GUARDEDALLOC_H__
+#define __MEM_GUARDEDALLOC_H__
 
-#include <stdio.h> /* needed for FILE* */
-#include "MEM_sys_types.h" /* needed for uintptr_t */
+#include <stdio.h>          /* needed for FILE* */
 
-#ifndef WARN_UNUSED
-#  ifdef __GNUC__
-#    define WARN_UNUSED  __attribute__((warn_unused_result))
-#  else
-#    define WARN_UNUSED
-#  endif
-#endif
+/* 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"
 
 #ifdef __cplusplus
 extern "C" {
@@ -91,99 +64,188 @@ extern "C" {
        /** 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(void *vmemh) WARN_UNUSED;
+       extern size_t (*MEM_allocN_len)(const void *vmemh) ATTR_WARN_UNUSED_RESULT;
 
        /**
-        * Release memory previously allocatred by this module. 
+        * Release memory previously allocated by this module.
         */
-       short 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.  */
-       LIBEXPORT void *MEM_dupallocN(void *vmemh) WARN_UNUSED;
+       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(void *vmemh, size_t len) WARN_UNUSED;
+        * 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 ! */
-       void *MEM_callocN(size_t len, const char * str) WARN_UNUSED;
-       
-       /** 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) WARN_UNUSED;
-       
-       /** 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) WARN_UNUSED;
+       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 */ 
-       void MEM_printmemlist_pydict(void);
+        * 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. */ 
-       void MEM_printmemlist(void);
+        * blocks. */
+       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. */
-       int MEM_check_memory_integrity(void);
+        * @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. */
-       void MEM_set_lock_callback(void (*lock)(void), void (*unlock)(void));
-       
+        * 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 */
-       void MEM_set_memory_debug(void);
+       extern void (*MEM_set_memory_debug)(void);
 
-       /** Memory usage stats
+       /**
+        * 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 size_t (*MEM_get_memory_in_use)(void);
        /** Get mapped memory usage. */
-       uintptr_t MEM_get_mapped_memory_in_use(void);
+       extern size_t (*MEM_get_mapped_memory_in_use)(void);
        /** Get amount of memory blocks in use. */
-       int MEM_get_memory_blocks_in_use(void);
+       extern unsigned int (*MEM_get_memory_blocks_in_use)(void);
 
        /** Reset the peak memory statistic to zero. */
-       void MEM_reset_peak_memory(void);
+       extern void (*MEM_reset_peak_memory)(void);
 
        /** Get the peak memory usage in bytes, including mmap allocations. */
-       uintptr_t MEM_get_peak_memory(void) WARN_UNUSED;
+       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)
+#else
+#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)
 
 #ifndef NDEBUG
-const char *MEM_name_ptr(void *vmemh);
+extern const char *(*MEM_name_ptr)(void *vmemh);
 #endif
-       
+
+/* Switch allocator to slower but fully guarded mode. */
+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 */
 
-#endif
+#ifdef __cplusplus
+}
+#endif  /* __cplusplus */
 
+#endif  /* __MEM_GUARDEDALLOC_H__ */