Changeset 648
- Timestamp:
- May 12, 2004, 9:05:02 AM (22 years ago)
- Location:
- trunk/psLib/src
- Files:
-
- 5 edited
-
Doxyfile (modified) (3 diffs)
-
sys/psMemory.c (modified) (16 diffs)
-
sys/psMemory.h (modified) (4 diffs)
-
sysUtils/psMemory.c (modified) (16 diffs)
-
sysUtils/psMemory.h (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/Doxyfile
r515 r648 15 15 #--------------------------------------------------------------------------- 16 16 17 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded 17 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded 18 18 # by quotes) that should identify the project. 19 19 … … 833 833 834 834 #--------------------------------------------------------------------------- 835 # Configuration options related to the preprocessor 836 #--------------------------------------------------------------------------- 837 838 # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 839 # evaluate all C-preprocessor directives found in the sources and include 835 # Configuration options related to the preprocessor 836 #--------------------------------------------------------------------------- 837 838 # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 839 # evaluate all C-preprocessor directives found in the sources and include 840 840 # files. 841 841 … … 874 874 875 875 # The PREDEFINED tag can be used to specify one or more macro names that 876 # are defined before the preprocessor is started (similar to the -D option of 877 # gcc). The argument of the tag is a list of macros of the form: name 878 # or name=definition (no spaces). If the definition and the = are 876 # are defined before the preprocessor is started (similar to the -D option of 877 # gcc). The argument of the tag is a list of macros of the form: name 878 # or name=definition (no spaces). If the definition and the = are 879 879 # omitted =1 is assumed. 880 880 881 PREDEFINED = 882 883 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 884 # this tag can be used to specify a list of macro names that should be expanded. 881 PREDEFINED = DOXYGEN 882 883 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 884 # this tag can be used to specify a list of macro names that should be expanded. 885 885 # The macro definition that is found in the sources will be used. 886 886 # Use the PREDEFINED tag if you want to use a different macro definition. -
trunk/psLib/src/sys/psMemory.c
r639 r648 8 8 * @author Robert Lupton, Princeton University 9 9 * 10 * @version $Revision: 1.1 7$ $Name: not supported by cvs2svn $11 * @date $Date: 2004-05-1 1 20:11:17$10 * @version $Revision: 1.18 $ $Name: not supported by cvs2svn $ 11 * @date $Date: 2004-05-12 19:05:02 $ 12 12 * 13 13 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 20 20 #include <stdio.h> 21 21 #include <stdbool.h> 22 #include <stdint.h> 22 23 23 24 #include "psMemory.h" … … 34 35 * Unique ID for allocated blocks 35 36 */ 36 static unsigned longmemid = 0;37 static psMemoryId memid = 0; 37 38 38 39 /** … … 62 63 const char *file, int lineno) 63 64 { 64 if (ptr->refCounter < = 0) {65 if (ptr->refCounter < 1) { 65 66 psError(__func__, 66 67 "Block %ld allocated at %s:%d freed more than once at %s:%d\n", … … 95 96 * Call the callbacks when these IDs are allocated/freed 96 97 */ 97 longp_psMemAllocateID = 0; // notify user this block is allocated98 longp_psMemFreeID = 0; // notify user this block is freed99 100 long psMemAllocateCallbackSetID(longid) // set p_psMemAllocateID to id101 { 102 longold = p_psMemAllocateID;98 psMemoryId p_psMemAllocateID = 0; // notify user this block is allocated 99 psMemoryId p_psMemFreeID = 0; // notify user this block is freed 100 101 psMemoryId psMemAllocateCallbackSetID(psMemoryId id) // set p_psMemAllocateID to id 102 { 103 psMemoryId old = p_psMemAllocateID; 103 104 p_psMemAllocateID = id; 104 105 … … 106 107 } 107 108 108 long psMemFreeCallbackSetID(longid) // set p_psMemFreeID to id109 { 110 longold = p_psMemFreeID;109 psMemoryId psMemFreeCallbackSetID(psMemoryId id) // set p_psMemFreeID to id 110 { 111 psMemoryId old = p_psMemFreeID; 111 112 p_psMemFreeID = id; 112 113 … … 120 121 * isn't resignalled) 121 122 */ 122 static longmemAllocateCallbackDefault(const psMemBlock *ptr)123 { 124 static intincr = 0; // "p_psMemAllocateID += incr"123 static psMemoryId memAllocateCallbackDefault(const psMemBlock *ptr) 124 { 125 static psMemoryId incr = 0; // "p_psMemAllocateID += incr" 125 126 126 127 return incr; 127 128 } 128 129 129 static longmemFreeCallbackDefault(const psMemBlock *ptr)130 { 131 static intincr = 0; // "p_psMemFreeID += incr"130 static psMemoryId memFreeCallbackDefault(const psMemBlock *ptr) 131 { 132 static psMemoryId incr = 0; // "p_psMemFreeID += incr" 132 133 133 134 return incr; … … 169 170 * Return memory ID counter for next block to be allocated 170 171 */ 171 intpsMemGetId(void)172 psMemoryId psMemGetId(void) 172 173 { 173 174 return memid + 1; … … 199 200 200 201 if (m->startblock != P_PS_MEMMAGIC || m->endblock != P_PS_MEMMAGIC) { 201 psError(funcName, "psMemCheckCorruption: memory block %ld is corrupted ( %p %p)",202 psError(funcName, "psMemCheckCorruption: memory block %ld is corrupted (buffer underflow %p %p)", 202 203 m->id,m->startblock,m->endblock); 204 return(1); 205 } 206 if (*(void**)((int8_t*)(m+1)+m->userMemorySize) != P_PS_MEMMAGIC) { 207 psError(funcName, "psMemCheckCorruption: memory block %ld is corrupted (buffer overflow, %p)", 208 m->id,*(void**)((int8_t*)(m+1)+m->userMemorySize)); 203 209 return(1); 204 210 } … … 236 242 void *p_psAlloc(size_t size, const char *file, int lineno) 237 243 { 238 psMemBlock *ptr = malloc(sizeof(psMemBlock) + size );244 psMemBlock *ptr = malloc(sizeof(psMemBlock) + size + sizeof(void*)); 239 245 240 246 if (ptr == NULL) { … … 246 252 } 247 253 248 *( unsigned long*)&ptr->id = ++memid;254 *(psMemoryId*)&ptr->id = ++memid; 249 255 ptr->file = file; 250 256 *(unsigned int*)&ptr->lineno = lineno; … … 252 258 ptr->endblock = P_PS_MEMMAGIC; 253 259 ptr->refCounter = 1; // one user so far 260 ptr->userMemorySize = size; 261 *(void**)((int8_t*)(ptr+1)+size) = P_PS_MEMMAGIC; 254 262 255 263 // need exclusive access of the memory block list now... … … 287 295 isBlockLast = (ptr == lastMemBlockAllocated); 288 296 289 ptr = (psMemBlock*)realloc(ptr, sizeof(psMemBlock) + size );297 ptr = (psMemBlock*)realloc(ptr, sizeof(psMemBlock) + size + sizeof(void*)); 290 298 291 299 if (ptr == NULL) { … … 293 301 size, file, lineno); 294 302 } 303 304 ptr->userMemorySize = size; 305 *(void**)((int8_t*)(ptr+1)+size) = P_PS_MEMMAGIC; 295 306 296 307 if (isBlockLast) { … … 363 374 */ 364 375 int psMemCheckLeaks( 365 int id0,// don't list blocks with id < id0376 psMemoryId id0, // don't list blocks with id < id0 366 377 psMemBlock ***arr, // pointer to array of pointers to leaked blocks, or NULL 367 378 FILE *fd) // print list of leaks to fd (or NULL) … … 416 427 * Reference counting APIs 417 428 */ 418 int psMemGetRefCounter(void *vptr) // return refCounter429 psReferenceCount psMemGetRefCounter(void *vptr) // return refCounter 419 430 { 420 431 psMemBlock *ptr = ((psMemBlock *)vptr) - 1; -
trunk/psLib/src/sys/psMemory.h
r639 r648 12 12 * @author Robert Lupton, Princeton University 13 13 * 14 * @version $Revision: 1.10 $ $Name: not supported by cvs2svn $ 15 * @date $Date: 2004-05-11 20:11:17 $ 14 * @version $Revision: 1.11 $ $Name: not supported by cvs2svn $ 15 * @date $Date: 2004-05-12 19:05:02 $ 16 * 17 * @ingroup SystemGroup System Utilities 16 18 * 17 19 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 19 21 20 22 #include <stdio.h> // needed for FILE 23 24 25 /** @addtogroup MemoryManagement Memory Management Utilities 26 * @ingroup SystemGroup 27 * 28 * This is the generic memory management system put inbetween the user's high level code and the OS-level 29 * memory allocation routines. This system adds such features as callback routines for memory error events, 30 * tracing capabilities, and reference counting. 31 * @{ 32 */ 33 34 /** 35 * @addtogroup memCallback Memory Callbacks 36 * 37 * Routines dealing with the creating and setting of memory management callback functions. 38 */ 39 40 /** 41 * @addtogroup memRefCount Reference Count 42 * 43 * Routines dealing with the reference counting of allocated buffers. 44 */ 45 46 /// typedef for memory identification numbers. Guaranteed to be some variety of integer. 47 typedef unsigned long psMemoryId; 48 49 /// typedef for a memory block's reference count. Guaranteed to be some variety of integer. 50 typedef unsigned long psReferenceCount; 21 51 22 52 /** Book-keeping data for storage allocator. … … 30 60 struct psMemBlock* previousBlock; ///< previous block in allocation list 31 61 struct psMemBlock* nextBlock; ///< next block allocation list 32 const unsigned long id; ///< a unique ID for this allocation 62 size_t userMemorySize; ///< the size of the user-portion of the memory block 63 const psMemoryId id; ///< a unique ID for this allocation 33 64 const char* file; ///< set from __FILE__ in e.g. p_psAlloc 34 65 const int lineno; ///< set from __LINE__ in e.g. p_psAlloc 35 unsigned int refCounter; ///< how many times pointer is referenced66 psReferenceCount refCounter; ///< how many times pointer is referenced 36 67 const void* endblock; ///< initialised to p_psMEMMAGIC 37 68 } 38 69 psMemBlock; 39 70 40 /// prototype of a basic callback used by memory functions 41 typedef long (*psMemAllocateCallback)(const psMemBlock *ptr); 42 43 /// prototype of memory free callback used by memory functions 44 typedef long (*psMemFreeCallback)(const psMemBlock *ptr); 71 /** prototype of a basic callback used by memory functions 72 * 73 * @see psMemAllocateCallbackSet 74 * @ingroup memCallback 75 */ 76 typedef psMemoryId (*psMemAllocateCallback)( 77 const psMemBlock *ptr ///< the psMemBlock just allocated 78 ); 79 80 /** prototype of memory free callback used by memory functions 81 * 82 * @see psMemFreeCallbackSet 83 * @ingroup memCallback 84 */ 85 typedef psMemoryId (*psMemFreeCallback)( 86 const psMemBlock *ptr ///< the psMemBlock being freed 87 ); 45 88 46 89 /** prototype of a callback used in error conditions 47 90 * 48 * This callback should never try to call psAlloc or psFree. 49 * 50 */ 51 typedef void (*psMemProblemCallback)(const psMemBlock *ptr, const char *file, int lineno); 52 53 /// prototype of a callback used when memory runs out 54 typedef void *(*psMemExhaustedCallback)(size_t size); 55 56 /** Private Functions **************************************************************/ 57 /** \addtogroup sysUtils memory private 58 * \{ 59 */ 60 61 /// Memory allocation. Underlying private function called by macro psAlloc. 62 void* p_psAlloc(size_t size, ///< Size required 63 const char *file, ///< File of call 64 int lineno) ///< Line number of call 65 ; 66 67 /// Memory re-allocation. Underlying private function called by macro psRealloc. 68 void* p_psRealloc(void *ptr, ///< Pointer to re-allocate 69 size_t size, ///< Size required 70 const char *file, ///< File of call 71 int lineno) ///< Line number of call 72 ; 73 74 /// Free memory. Underlying private function called by macro psFree. 75 void p_psFree(void *ptr, ///< Pointer to free 76 const char *file, ///< File of call 77 int lineno) ///< Line number of call 78 ; 79 /** Public Functions **************************************************************/ 80 /** \} 81 * \addtogroup sysUtils memory psLibAPI 82 * \{ 83 */ 84 85 /// Check for memory leaks 91 * This callback should not try to call psAlloc or psFree. 92 * 93 * @see psMemProblemCallbackSet 94 * @ingroup memCallback 95 */ 96 typedef void (*psMemProblemCallback)( 97 const psMemBlock *ptr, ///< the pointer to the problematic memory block. 98 const char *file, ///< the file in which the problem originated 99 int lineno ///< the line number in which the problem originated 100 ); 101 102 /** prototype of a callback function used when memory runs out 103 * 104 * @return void* pointer to requested buffer of the size size_t, or NULL if memory could not 105 * be found. 106 * 107 * @see psMemExhaustedCallbackSet 108 * @ingroup memCallback 109 */ 110 typedef void *(*psMemExhaustedCallback)( 111 size_t size //< the size of buffer required 112 ); 113 114 /** Memory allocation. This operates much like malloc(), but is guaranteed to return a non-NULL value. 115 * 116 * @return void* pointer to the allocated buffer. This will not be NULL. 117 * @see psFree 118 */ 119 #ifdef DOXYGEN 120 void* psAlloc( 121 size_t size ///< Size required 122 ); 123 #else 124 void* p_psAlloc( 125 size_t size, ///< Size required 126 const char *file, ///< File of call 127 int lineno ///< Line number of call 128 ); 129 /// Memory allocation. psAlloc sends file and line number to p_psAlloc. 130 #define psAlloc(size) p_psAlloc(size, __FILE__, __LINE__) 131 #endif 132 133 134 /** Memory re-allocation. This operates much like realloc(), but is guaranteed to return a non-NULL value. 135 * 136 * @return void* pointer to resized buffer. This will not be NULL. 137 * @see psAlloc, psFree 138 */ 139 #ifdef DOXYGEN 140 void* psRealloc(void *ptr ///< Pointer to re-allocate 141 ); 142 #else 143 void* p_psRealloc(void *ptr, ///< Pointer to re-allocate 144 size_t size, ///< Size required 145 const char *file, ///< File of call 146 int lineno ///< Line number of call 147 ); 148 149 /// Memory re-allocation. psRealloc sends file and line number to p_psRealloc. 150 #define psRealloc(ptr, size) p_psRealloc(ptr, size, __FILE__, __LINE__) 151 152 #endif 153 154 155 /** Free memory. This operates much like free(). 156 * 157 * @see psAlloc, psRealloc 158 */ 159 #ifdef DOXYGEN 160 void psFree(void *ptr, ///< Pointer to free, if NULL, function returns immediately. 161 ); 162 #else 163 void p_psFree(void *ptr, ///< Pointer to free 164 const char *file, ///< File of call 165 int lineno ///< Line number of call 166 ); 167 168 /// Free memory. psFree sends file and line number to p_psFree. 169 #define psFree(size) p_psFree(size, __FILE__, __LINE__) 170 171 #endif 172 173 /** Check for memory leaks. This scans for allocated memory buffers not freed with an ID not less than id0. 174 * This is used to check for memory leaks by: 175 * -# before a block of code to be checked, store the current ID count via psGetMemId 176 * -# after the block of code to be checked, call this function using the ID stored above. If all 177 * memory in the block that was allocated has been freed, this call should output nothing and 178 * return 0. 179 * 180 * If memory leaks are found, the Memory Problem callback will be called as well. 181 * 182 * return int number of memory blocks found as 'leaks', i.e., the number of currently allocated memory 183 * blocks above id0 that have not been freed. 184 * @see psAlloc, psFree, psgetMemId, psMemProblemCallbackSet 185 */ 86 186 int psMemCheckLeaks( 87 int id0,///< don't list blocks with id < id0187 psMemoryId id0, ///< don't list blocks with id < id0 88 188 psMemBlock ***arr, ///< pointer to array of pointers to leaked blocks, or NULL 89 189 FILE *fd ///< print list of leaks to fd (or NULL) 90 190 ); 91 191 92 /// Check for memory corruption 192 /** Check for memory corruption. Scans all currently allocated memory buffers and checks for corruptions, 193 * i.e., invalid markers that signify a buffer under/overflow. 194 * 195 */ 93 196 int psMemCheckCorruption( 94 197 int abort_on_error ///< Abort on detecting corruption? 95 198 ); 96 199 97 /// Return reference counter 98 int psMemGetRefCounter( 200 /** Return reference counter 201 * 202 * @ingroup memRefCount 203 */ 204 psReferenceCount psMemGetRefCounter( 99 205 void *vptr ///< Pointer to get refCounter for 100 206 ); 101 207 102 /// Increment reference counter and return the pointer 208 /** Increment reference counter and return the pointer 209 * 210 * @ingroup memRefCount 211 */ 103 212 void *psMemIncrRefCounter( 104 213 void *vptr ///< Pointer to increment refCounter, and return 105 214 ); 106 215 107 /// Decrement reference counter and return the pointer 216 /** Decrement reference counter and return the pointer 217 * 218 * @ingroup memRefCount 219 */ 108 220 void *psMemDecrRefCounter( 109 221 void *vptr ///< Pointer to decrement refCounter, and return 110 222 ); 111 223 112 /// Set callback for problems 224 /** Set callback for problems 225 * @ingroup memCallback 226 */ 113 227 psMemProblemCallback psMemProblemCallbackSet( 114 228 psMemProblemCallback func ///< Function to run 115 229 ); 116 230 117 /// Set callback for out-of-memory 231 /** Set callback for out-of-memory 232 * 233 * @ingroup memCallback 234 */ 118 235 psMemExhaustedCallback psMemExhaustedCallbackSet( 119 236 psMemExhaustedCallback func ///< Function to run 120 237 ); 121 238 122 /// Set call back for when a particular memory block is allocated 239 /** Set call back for when a particular memory block is allocated 240 * 241 * @ingroup memCallback 242 */ 123 243 psMemAllocateCallback psMemAllocateCallbackSet( 124 psMemAllocateCallback func ///< Function to run 125 ); 126 127 /// Set call back for when a particular memory block is freed 244 psMemAllocateCallback func ///< Function to run 245 ); 246 247 /** Set call back for when a particular memory block is freed 248 * 249 * @ingroup memCallback 250 */ 128 251 psMemFreeCallback psMemFreeCallbackSet( 129 psMemFreeCallback func ///< Function to run 130 ); 131 132 /// get next memory ID 133 int psMemGetId(void) 134 ; 135 136 /// set p_psMemAllocateID to id 137 long psMemAllocateCallbackSetID( 138 long id ///< ID to set 139 ); 140 141 /// set p_psMemFreeID to id 142 long psMemFreeCallbackSetID( 143 long id ///< ID to set 144 ); 145 146 //@} End of public Functions 147 148 /// Memory allocation. psAlloc sends file and line number to p_psAlloc. 149 #define psAlloc(size) p_psAlloc(size, __FILE__, __LINE__) 150 151 /// Memory re-allocation. psRealloc sends file and line number to p_psRealloc. 152 #define psRealloc(ptr, size) p_psRealloc(ptr, size, __FILE__, __LINE__) 153 154 /// Free memory. psFree sends file and line number to p_psFree. 155 #define psFree(size) p_psFree(size, __FILE__, __LINE__) 252 psMemFreeCallback func ///< Function to run 253 ); 254 255 /** get next memory ID 256 * 257 * @ingroup memCallback 258 */ 259 psMemoryId psMemGetId(void); 260 261 /** set p_psMemAllocateID to id 262 * 263 * @ingroup memCallback 264 */ 265 psMemoryId psMemAllocateCallbackSetID( 266 psMemoryId id ///< ID to set 267 ); 268 269 /** set p_psMemFreeID to id 270 * 271 * @ingroup memCallback 272 */ 273 psMemoryId psMemFreeCallbackSetID( 274 psMemoryId id ///< ID to set 275 ); 276 277 //@} End of Memory Management Functions 278 279 #ifndef DOXYGEN 156 280 157 281 /* … … 169 293 #endif 170 294 295 #endif // doxygen skip 296 171 297 #endif // end of header file -
trunk/psLib/src/sysUtils/psMemory.c
r639 r648 8 8 * @author Robert Lupton, Princeton University 9 9 * 10 * @version $Revision: 1.1 7$ $Name: not supported by cvs2svn $11 * @date $Date: 2004-05-1 1 20:11:17$10 * @version $Revision: 1.18 $ $Name: not supported by cvs2svn $ 11 * @date $Date: 2004-05-12 19:05:02 $ 12 12 * 13 13 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 20 20 #include <stdio.h> 21 21 #include <stdbool.h> 22 #include <stdint.h> 22 23 23 24 #include "psMemory.h" … … 34 35 * Unique ID for allocated blocks 35 36 */ 36 static unsigned longmemid = 0;37 static psMemoryId memid = 0; 37 38 38 39 /** … … 62 63 const char *file, int lineno) 63 64 { 64 if (ptr->refCounter < = 0) {65 if (ptr->refCounter < 1) { 65 66 psError(__func__, 66 67 "Block %ld allocated at %s:%d freed more than once at %s:%d\n", … … 95 96 * Call the callbacks when these IDs are allocated/freed 96 97 */ 97 longp_psMemAllocateID = 0; // notify user this block is allocated98 longp_psMemFreeID = 0; // notify user this block is freed99 100 long psMemAllocateCallbackSetID(longid) // set p_psMemAllocateID to id101 { 102 longold = p_psMemAllocateID;98 psMemoryId p_psMemAllocateID = 0; // notify user this block is allocated 99 psMemoryId p_psMemFreeID = 0; // notify user this block is freed 100 101 psMemoryId psMemAllocateCallbackSetID(psMemoryId id) // set p_psMemAllocateID to id 102 { 103 psMemoryId old = p_psMemAllocateID; 103 104 p_psMemAllocateID = id; 104 105 … … 106 107 } 107 108 108 long psMemFreeCallbackSetID(longid) // set p_psMemFreeID to id109 { 110 longold = p_psMemFreeID;109 psMemoryId psMemFreeCallbackSetID(psMemoryId id) // set p_psMemFreeID to id 110 { 111 psMemoryId old = p_psMemFreeID; 111 112 p_psMemFreeID = id; 112 113 … … 120 121 * isn't resignalled) 121 122 */ 122 static longmemAllocateCallbackDefault(const psMemBlock *ptr)123 { 124 static intincr = 0; // "p_psMemAllocateID += incr"123 static psMemoryId memAllocateCallbackDefault(const psMemBlock *ptr) 124 { 125 static psMemoryId incr = 0; // "p_psMemAllocateID += incr" 125 126 126 127 return incr; 127 128 } 128 129 129 static longmemFreeCallbackDefault(const psMemBlock *ptr)130 { 131 static intincr = 0; // "p_psMemFreeID += incr"130 static psMemoryId memFreeCallbackDefault(const psMemBlock *ptr) 131 { 132 static psMemoryId incr = 0; // "p_psMemFreeID += incr" 132 133 133 134 return incr; … … 169 170 * Return memory ID counter for next block to be allocated 170 171 */ 171 intpsMemGetId(void)172 psMemoryId psMemGetId(void) 172 173 { 173 174 return memid + 1; … … 199 200 200 201 if (m->startblock != P_PS_MEMMAGIC || m->endblock != P_PS_MEMMAGIC) { 201 psError(funcName, "psMemCheckCorruption: memory block %ld is corrupted ( %p %p)",202 psError(funcName, "psMemCheckCorruption: memory block %ld is corrupted (buffer underflow %p %p)", 202 203 m->id,m->startblock,m->endblock); 204 return(1); 205 } 206 if (*(void**)((int8_t*)(m+1)+m->userMemorySize) != P_PS_MEMMAGIC) { 207 psError(funcName, "psMemCheckCorruption: memory block %ld is corrupted (buffer overflow, %p)", 208 m->id,*(void**)((int8_t*)(m+1)+m->userMemorySize)); 203 209 return(1); 204 210 } … … 236 242 void *p_psAlloc(size_t size, const char *file, int lineno) 237 243 { 238 psMemBlock *ptr = malloc(sizeof(psMemBlock) + size );244 psMemBlock *ptr = malloc(sizeof(psMemBlock) + size + sizeof(void*)); 239 245 240 246 if (ptr == NULL) { … … 246 252 } 247 253 248 *( unsigned long*)&ptr->id = ++memid;254 *(psMemoryId*)&ptr->id = ++memid; 249 255 ptr->file = file; 250 256 *(unsigned int*)&ptr->lineno = lineno; … … 252 258 ptr->endblock = P_PS_MEMMAGIC; 253 259 ptr->refCounter = 1; // one user so far 260 ptr->userMemorySize = size; 261 *(void**)((int8_t*)(ptr+1)+size) = P_PS_MEMMAGIC; 254 262 255 263 // need exclusive access of the memory block list now... … … 287 295 isBlockLast = (ptr == lastMemBlockAllocated); 288 296 289 ptr = (psMemBlock*)realloc(ptr, sizeof(psMemBlock) + size );297 ptr = (psMemBlock*)realloc(ptr, sizeof(psMemBlock) + size + sizeof(void*)); 290 298 291 299 if (ptr == NULL) { … … 293 301 size, file, lineno); 294 302 } 303 304 ptr->userMemorySize = size; 305 *(void**)((int8_t*)(ptr+1)+size) = P_PS_MEMMAGIC; 295 306 296 307 if (isBlockLast) { … … 363 374 */ 364 375 int psMemCheckLeaks( 365 int id0,// don't list blocks with id < id0376 psMemoryId id0, // don't list blocks with id < id0 366 377 psMemBlock ***arr, // pointer to array of pointers to leaked blocks, or NULL 367 378 FILE *fd) // print list of leaks to fd (or NULL) … … 416 427 * Reference counting APIs 417 428 */ 418 int psMemGetRefCounter(void *vptr) // return refCounter429 psReferenceCount psMemGetRefCounter(void *vptr) // return refCounter 419 430 { 420 431 psMemBlock *ptr = ((psMemBlock *)vptr) - 1; -
trunk/psLib/src/sysUtils/psMemory.h
r639 r648 12 12 * @author Robert Lupton, Princeton University 13 13 * 14 * @version $Revision: 1.10 $ $Name: not supported by cvs2svn $ 15 * @date $Date: 2004-05-11 20:11:17 $ 14 * @version $Revision: 1.11 $ $Name: not supported by cvs2svn $ 15 * @date $Date: 2004-05-12 19:05:02 $ 16 * 17 * @ingroup SystemGroup System Utilities 16 18 * 17 19 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 19 21 20 22 #include <stdio.h> // needed for FILE 23 24 25 /** @addtogroup MemoryManagement Memory Management Utilities 26 * @ingroup SystemGroup 27 * 28 * This is the generic memory management system put inbetween the user's high level code and the OS-level 29 * memory allocation routines. This system adds such features as callback routines for memory error events, 30 * tracing capabilities, and reference counting. 31 * @{ 32 */ 33 34 /** 35 * @addtogroup memCallback Memory Callbacks 36 * 37 * Routines dealing with the creating and setting of memory management callback functions. 38 */ 39 40 /** 41 * @addtogroup memRefCount Reference Count 42 * 43 * Routines dealing with the reference counting of allocated buffers. 44 */ 45 46 /// typedef for memory identification numbers. Guaranteed to be some variety of integer. 47 typedef unsigned long psMemoryId; 48 49 /// typedef for a memory block's reference count. Guaranteed to be some variety of integer. 50 typedef unsigned long psReferenceCount; 21 51 22 52 /** Book-keeping data for storage allocator. … … 30 60 struct psMemBlock* previousBlock; ///< previous block in allocation list 31 61 struct psMemBlock* nextBlock; ///< next block allocation list 32 const unsigned long id; ///< a unique ID for this allocation 62 size_t userMemorySize; ///< the size of the user-portion of the memory block 63 const psMemoryId id; ///< a unique ID for this allocation 33 64 const char* file; ///< set from __FILE__ in e.g. p_psAlloc 34 65 const int lineno; ///< set from __LINE__ in e.g. p_psAlloc 35 unsigned int refCounter; ///< how many times pointer is referenced66 psReferenceCount refCounter; ///< how many times pointer is referenced 36 67 const void* endblock; ///< initialised to p_psMEMMAGIC 37 68 } 38 69 psMemBlock; 39 70 40 /// prototype of a basic callback used by memory functions 41 typedef long (*psMemAllocateCallback)(const psMemBlock *ptr); 42 43 /// prototype of memory free callback used by memory functions 44 typedef long (*psMemFreeCallback)(const psMemBlock *ptr); 71 /** prototype of a basic callback used by memory functions 72 * 73 * @see psMemAllocateCallbackSet 74 * @ingroup memCallback 75 */ 76 typedef psMemoryId (*psMemAllocateCallback)( 77 const psMemBlock *ptr ///< the psMemBlock just allocated 78 ); 79 80 /** prototype of memory free callback used by memory functions 81 * 82 * @see psMemFreeCallbackSet 83 * @ingroup memCallback 84 */ 85 typedef psMemoryId (*psMemFreeCallback)( 86 const psMemBlock *ptr ///< the psMemBlock being freed 87 ); 45 88 46 89 /** prototype of a callback used in error conditions 47 90 * 48 * This callback should never try to call psAlloc or psFree. 49 * 50 */ 51 typedef void (*psMemProblemCallback)(const psMemBlock *ptr, const char *file, int lineno); 52 53 /// prototype of a callback used when memory runs out 54 typedef void *(*psMemExhaustedCallback)(size_t size); 55 56 /** Private Functions **************************************************************/ 57 /** \addtogroup sysUtils memory private 58 * \{ 59 */ 60 61 /// Memory allocation. Underlying private function called by macro psAlloc. 62 void* p_psAlloc(size_t size, ///< Size required 63 const char *file, ///< File of call 64 int lineno) ///< Line number of call 65 ; 66 67 /// Memory re-allocation. Underlying private function called by macro psRealloc. 68 void* p_psRealloc(void *ptr, ///< Pointer to re-allocate 69 size_t size, ///< Size required 70 const char *file, ///< File of call 71 int lineno) ///< Line number of call 72 ; 73 74 /// Free memory. Underlying private function called by macro psFree. 75 void p_psFree(void *ptr, ///< Pointer to free 76 const char *file, ///< File of call 77 int lineno) ///< Line number of call 78 ; 79 /** Public Functions **************************************************************/ 80 /** \} 81 * \addtogroup sysUtils memory psLibAPI 82 * \{ 83 */ 84 85 /// Check for memory leaks 91 * This callback should not try to call psAlloc or psFree. 92 * 93 * @see psMemProblemCallbackSet 94 * @ingroup memCallback 95 */ 96 typedef void (*psMemProblemCallback)( 97 const psMemBlock *ptr, ///< the pointer to the problematic memory block. 98 const char *file, ///< the file in which the problem originated 99 int lineno ///< the line number in which the problem originated 100 ); 101 102 /** prototype of a callback function used when memory runs out 103 * 104 * @return void* pointer to requested buffer of the size size_t, or NULL if memory could not 105 * be found. 106 * 107 * @see psMemExhaustedCallbackSet 108 * @ingroup memCallback 109 */ 110 typedef void *(*psMemExhaustedCallback)( 111 size_t size //< the size of buffer required 112 ); 113 114 /** Memory allocation. This operates much like malloc(), but is guaranteed to return a non-NULL value. 115 * 116 * @return void* pointer to the allocated buffer. This will not be NULL. 117 * @see psFree 118 */ 119 #ifdef DOXYGEN 120 void* psAlloc( 121 size_t size ///< Size required 122 ); 123 #else 124 void* p_psAlloc( 125 size_t size, ///< Size required 126 const char *file, ///< File of call 127 int lineno ///< Line number of call 128 ); 129 /// Memory allocation. psAlloc sends file and line number to p_psAlloc. 130 #define psAlloc(size) p_psAlloc(size, __FILE__, __LINE__) 131 #endif 132 133 134 /** Memory re-allocation. This operates much like realloc(), but is guaranteed to return a non-NULL value. 135 * 136 * @return void* pointer to resized buffer. This will not be NULL. 137 * @see psAlloc, psFree 138 */ 139 #ifdef DOXYGEN 140 void* psRealloc(void *ptr ///< Pointer to re-allocate 141 ); 142 #else 143 void* p_psRealloc(void *ptr, ///< Pointer to re-allocate 144 size_t size, ///< Size required 145 const char *file, ///< File of call 146 int lineno ///< Line number of call 147 ); 148 149 /// Memory re-allocation. psRealloc sends file and line number to p_psRealloc. 150 #define psRealloc(ptr, size) p_psRealloc(ptr, size, __FILE__, __LINE__) 151 152 #endif 153 154 155 /** Free memory. This operates much like free(). 156 * 157 * @see psAlloc, psRealloc 158 */ 159 #ifdef DOXYGEN 160 void psFree(void *ptr, ///< Pointer to free, if NULL, function returns immediately. 161 ); 162 #else 163 void p_psFree(void *ptr, ///< Pointer to free 164 const char *file, ///< File of call 165 int lineno ///< Line number of call 166 ); 167 168 /// Free memory. psFree sends file and line number to p_psFree. 169 #define psFree(size) p_psFree(size, __FILE__, __LINE__) 170 171 #endif 172 173 /** Check for memory leaks. This scans for allocated memory buffers not freed with an ID not less than id0. 174 * This is used to check for memory leaks by: 175 * -# before a block of code to be checked, store the current ID count via psGetMemId 176 * -# after the block of code to be checked, call this function using the ID stored above. If all 177 * memory in the block that was allocated has been freed, this call should output nothing and 178 * return 0. 179 * 180 * If memory leaks are found, the Memory Problem callback will be called as well. 181 * 182 * return int number of memory blocks found as 'leaks', i.e., the number of currently allocated memory 183 * blocks above id0 that have not been freed. 184 * @see psAlloc, psFree, psgetMemId, psMemProblemCallbackSet 185 */ 86 186 int psMemCheckLeaks( 87 int id0,///< don't list blocks with id < id0187 psMemoryId id0, ///< don't list blocks with id < id0 88 188 psMemBlock ***arr, ///< pointer to array of pointers to leaked blocks, or NULL 89 189 FILE *fd ///< print list of leaks to fd (or NULL) 90 190 ); 91 191 92 /// Check for memory corruption 192 /** Check for memory corruption. Scans all currently allocated memory buffers and checks for corruptions, 193 * i.e., invalid markers that signify a buffer under/overflow. 194 * 195 */ 93 196 int psMemCheckCorruption( 94 197 int abort_on_error ///< Abort on detecting corruption? 95 198 ); 96 199 97 /// Return reference counter 98 int psMemGetRefCounter( 200 /** Return reference counter 201 * 202 * @ingroup memRefCount 203 */ 204 psReferenceCount psMemGetRefCounter( 99 205 void *vptr ///< Pointer to get refCounter for 100 206 ); 101 207 102 /// Increment reference counter and return the pointer 208 /** Increment reference counter and return the pointer 209 * 210 * @ingroup memRefCount 211 */ 103 212 void *psMemIncrRefCounter( 104 213 void *vptr ///< Pointer to increment refCounter, and return 105 214 ); 106 215 107 /// Decrement reference counter and return the pointer 216 /** Decrement reference counter and return the pointer 217 * 218 * @ingroup memRefCount 219 */ 108 220 void *psMemDecrRefCounter( 109 221 void *vptr ///< Pointer to decrement refCounter, and return 110 222 ); 111 223 112 /// Set callback for problems 224 /** Set callback for problems 225 * @ingroup memCallback 226 */ 113 227 psMemProblemCallback psMemProblemCallbackSet( 114 228 psMemProblemCallback func ///< Function to run 115 229 ); 116 230 117 /// Set callback for out-of-memory 231 /** Set callback for out-of-memory 232 * 233 * @ingroup memCallback 234 */ 118 235 psMemExhaustedCallback psMemExhaustedCallbackSet( 119 236 psMemExhaustedCallback func ///< Function to run 120 237 ); 121 238 122 /// Set call back for when a particular memory block is allocated 239 /** Set call back for when a particular memory block is allocated 240 * 241 * @ingroup memCallback 242 */ 123 243 psMemAllocateCallback psMemAllocateCallbackSet( 124 psMemAllocateCallback func ///< Function to run 125 ); 126 127 /// Set call back for when a particular memory block is freed 244 psMemAllocateCallback func ///< Function to run 245 ); 246 247 /** Set call back for when a particular memory block is freed 248 * 249 * @ingroup memCallback 250 */ 128 251 psMemFreeCallback psMemFreeCallbackSet( 129 psMemFreeCallback func ///< Function to run 130 ); 131 132 /// get next memory ID 133 int psMemGetId(void) 134 ; 135 136 /// set p_psMemAllocateID to id 137 long psMemAllocateCallbackSetID( 138 long id ///< ID to set 139 ); 140 141 /// set p_psMemFreeID to id 142 long psMemFreeCallbackSetID( 143 long id ///< ID to set 144 ); 145 146 //@} End of public Functions 147 148 /// Memory allocation. psAlloc sends file and line number to p_psAlloc. 149 #define psAlloc(size) p_psAlloc(size, __FILE__, __LINE__) 150 151 /// Memory re-allocation. psRealloc sends file and line number to p_psRealloc. 152 #define psRealloc(ptr, size) p_psRealloc(ptr, size, __FILE__, __LINE__) 153 154 /// Free memory. psFree sends file and line number to p_psFree. 155 #define psFree(size) p_psFree(size, __FILE__, __LINE__) 252 psMemFreeCallback func ///< Function to run 253 ); 254 255 /** get next memory ID 256 * 257 * @ingroup memCallback 258 */ 259 psMemoryId psMemGetId(void); 260 261 /** set p_psMemAllocateID to id 262 * 263 * @ingroup memCallback 264 */ 265 psMemoryId psMemAllocateCallbackSetID( 266 psMemoryId id ///< ID to set 267 ); 268 269 /** set p_psMemFreeID to id 270 * 271 * @ingroup memCallback 272 */ 273 psMemoryId psMemFreeCallbackSetID( 274 psMemoryId id ///< ID to set 275 ); 276 277 //@} End of Memory Management Functions 278 279 #ifndef DOXYGEN 156 280 157 281 /* … … 169 293 #endif 170 294 295 #endif // doxygen skip 296 171 297 #endif // end of header file
Note:
See TracChangeset
for help on using the changeset viewer.
