1 /** 2 * @file memoryzone.h 3 * Memory zone. 4 * 5 * @par Build Options 6 * Define the macro @c LIBDENG_FAKE_MEMORY_ZONE to force all memory blocks to be 7 * allocated from the real heap. Useful when debugging memory-related problems. 8 * 9 * @authors Copyright © 1999-2017 Jaakko Keränen <jaakko.keranen@iki.fi> 10 * @authors Copyright © 2006-2013 Daniel Swanson <danij@dengine.net> 11 * @authors Copyright © 1993-1996 by id Software, Inc. 12 * 13 * @par License 14 * GPL: http://www.gnu.org/licenses/gpl.html 15 * 16 * <small>This program is free software; you can redistribute it and/or modify 17 * it under the terms of the GNU General Public License as published by the 18 * Free Software Foundation; either version 2 of the License, or (at your 19 * option) any later version. This program is distributed in the hope that it 20 * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty 21 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 22 * Public License for more details. You should have received a copy of the GNU 23 * General Public License along with this program; if not, write to the Free 24 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 25 * 02110-1301 USA</small> 26 */ 27 28 #ifndef LIBDENG_MEMORY_ZONE_H 29 #define LIBDENG_MEMORY_ZONE_H 30 31 /** 32 * @defgroup memzone Memory Zone 33 * @ingroup legacy 34 */ 35 36 #include <de/liblegacy.h> 37 38 #ifdef __cplusplus 39 extern "C" { 40 #endif 41 42 /** 43 * @defgroup purgeLevels Purge Levels 44 * @ingroup memzone 45 */ 46 ///@{ 47 #define PU_APPSTATIC 1 ///< Static entire execution time. 48 49 #define PU_GAMESTATIC 40 ///< Static until the game plugin which allocated it is unloaded. 50 #define PU_MAP 50 ///< Static until map exited (may still be freed during the map, though). 51 #define PU_MAPSTATIC 52 ///< Not freed until map exited. 52 53 #define PU_PURGELEVEL 100 ///< Tags >= 100 are purgable whenever needed. 54 ///@} 55 56 #define LIBDENG_ZONEID 0x1d4a11 57 58 /// @addtogroup memzone 59 ///@{ 60 61 /** 62 * Determines if the memory zone is available for allocations. 63 */ 64 DENG_PUBLIC dd_bool Z_IsInited(void); 65 66 /** 67 * You can pass a NULL user if the tag is < PU_PURGELEVEL. 68 */ 69 DENG_PUBLIC void *Z_Malloc(size_t size, int tag, void *ptr); 70 71 /** 72 * Memory allocation utility: malloc and clear. 73 */ 74 DENG_PUBLIC void *Z_Calloc(size_t size, int tag, void *user); 75 76 /** 77 * Only resizes blocks with no user. If a block with a user is 78 * reallocated, the user will lose its current block and be set to 79 * NULL. Does not change the tag of existing blocks. 80 */ 81 DENG_PUBLIC void *Z_Realloc(void *ptr, size_t n, int mallocTag); 82 83 /** 84 * Realloc and set possible new memory to zero. 85 */ 86 DENG_PUBLIC void *Z_Recalloc(void *ptr, size_t n, int callocTag); 87 88 /** 89 * Free memory that was allocated with Z_Malloc. 90 */ 91 DENG_PUBLIC void Z_Free(void *ptr); 92 93 /** 94 * Free memory blocks in all volumes with a tag in the specified range. 95 */ 96 DENG_PUBLIC void Z_FreeTags(int lowTag, int highTag); 97 98 /** 99 * Check all zone volumes for consistency. 100 */ 101 DENG_PUBLIC void Z_CheckHeap(void); 102 103 /** 104 * Change the tag of a memory block. 105 */ 106 DENG_PUBLIC void Z_ChangeTag2(void *ptr, int tag); 107 108 /** 109 * Change the user of a memory block. 110 */ 111 DENG_PUBLIC void Z_ChangeUser(void *ptr, void *newUser); 112 113 DENG_PUBLIC uint32_t Z_GetId(void *ptr); 114 115 /** 116 * Get the user of a memory block. 117 */ 118 DENG_PUBLIC void *Z_GetUser(void *ptr); 119 120 DENG_PUBLIC int Z_GetTag(void *ptr); 121 122 /** 123 * Checks if @a ptr points to memory inside the memory zone. 124 * @param ptr Pointer. 125 * @return @c true, if @a ptr points to a valid allocated memory block 126 * inside the zone. 127 */ 128 DENG_PUBLIC dd_bool Z_Contains(void *ptr); 129 130 /** 131 * Copies @a text into a buffer allocated from the zone. 132 * Similar to strdup(). 133 * 134 * @param text Null-terminated C string. 135 * 136 * @return Copy of the string (in the zone). 137 */ 138 DENG_PUBLIC char *Z_StrDup(char const *text); 139 140 DENG_PUBLIC void *Z_MemDup(void const *ptr, size_t size); 141 142 struct zblockset_s; 143 typedef struct zblockset_s zblockset_t; 144 145 /** 146 * Creates a new block memory allocator in the Zone. 147 * 148 * @param sizeOfElement Required size of each element. 149 * @param batchSize Number of elements in each block of the set. 150 * @param tag Purge level for the allocation. 151 * 152 * @return Ptr to the newly created blockset. 153 */ 154 DENG_PUBLIC zblockset_t *ZBlockSet_New(size_t sizeOfElement, uint32_t batchSize, int tag); 155 156 /** 157 * Destroy the entire blockset. 158 * All memory allocated is released for all elements in all blocks and any 159 * used for the blockset itself. 160 * 161 * @param set The blockset to be freed. 162 */ 163 DENG_PUBLIC void ZBlockSet_Delete(zblockset_t *set); 164 165 /** 166 * Return a ptr to the next unused element in the blockset. 167 * 168 * @param set The blockset to return the next element from. 169 * 170 * @return Ptr to the next unused element in the blockset. 171 */ 172 DENG_PUBLIC void *ZBlockSet_Allocate(zblockset_t *set); 173 174 #define Z_ChangeTag(p,t) { \ 175 if (Z_GetId(p) != LIBDENG_ZONEID) \ 176 Con_Error("Z_ChangeTag at " __FILE__ ":%i", __LINE__); \ 177 Z_ChangeTag2(p, t); } 178 179 DENG_PUBLIC void Z_PrintStatus(void); 180 181 /** 182 * Puts a region of memory allocated with Z_Malloc() or malloc() up for garbage 183 * collection. 184 * 185 * @param ptr Allocated memory (not previously trashed). 186 */ 187 DENG_PUBLIC void Garbage_Trash(void *ptr); 188 189 ///@} 190 191 #ifdef DENG_DEBUG 192 struct memzone_private_s; 193 typedef struct memzone_private_s MemoryZonePrivateData; 194 DENG_PUBLIC void Z_GetPrivateData(MemoryZonePrivateData *pd); 195 #endif 196 197 #ifdef __cplusplus 198 } // extern "C" 199 #endif 200 201 #endif // LIBDENG_MEMORY_ZONE_H 202