57 struct MemoryListLink * listEnter; /* pointer to the free list node */
58 byte_t guard[MAX_GUARD_BYTES]; /* guard area for underrun check */
59 } MemoryBlockHeader;
60
61 /* Tail to follow allocated block */
62 typedef struct MemoryBlockTail {
63 byte_t guard[MAX_GUARD_BYTES]; /* guard area overrun check */
64 } MemoryBlockTail;
65
66 /* Linked list of allocated memory blocks */
67 typedef struct MemoryListLink {
68 struct MemoryListLink * next;
69 MemoryBlockHeader * header;
70 int freed;
71 } MemoryListLink;
72
73 /**************************************************
74 * Global Data structures
75 */
76 static DMemState DMemGlobalState;
77 extern const DMemState * DMemStatePtr = &DMemGlobalState;
78 static MemoryListLink MemoryList = {NULL,NULL,FALSE};
79 static dmutex_t DMemMutex = NULL;
80
81 /**************************************************/
82
83 /*************************************************
84 * Client callback invocation functions
85 */
86 static void * DMem_ClientAllocate(size_t size) {
87 if (DMemGlobalState.pfnAlloc != NULL) {
88 return (*DMemGlobalState.pfnAlloc)(size);
89 }
90 return malloc(size);
91 }
92
93 static void DMem_ClientFree(void * ptr) {
94 if (DMemGlobalState.pfnFree != NULL) {
95 (*DMemGlobalState.pfnFree)(ptr);
96 }
97 free(ptr);
259
260 DMutex_Enter(DMemMutex);
261 if ( memptr == NULL) {
262 goto Exit;
263 }
264
265 /* get the debug block header preceding the allocated memory */
266 header = DMem_GetHeader(memptr);
267 /* fill memory with recognizable 'freed' value */
268 memset(memptr, ByteFreed, header->size);
269 /* mark block as freed */
270 header->listEnter->freed = TRUE;
271 /* update used memory total */
272 DMemGlobalState.totalHeapUsed -= header->size;
273 Exit:
274 DMutex_Exit(DMemMutex);
275 }
276
277 static void DMem_DumpHeader(MemoryBlockHeader * header) {
278 char report[FILENAME_MAX+MAX_DECIMAL_DIGITS*3+1];
279 static const char * reportFormat =
280 "file: %s, line %d\n"
281 "size: %d bytes\n"
282 "order: %d\n"
283 "-------";
284
285 DMem_VerifyHeader(header);
286 sprintf(report, reportFormat, header->filename, header->linenumber, header->size, header->order);
287 DTRACE_PRINTLN(report);
288 }
289
290 /*
291 * Call this function at shutdown time to report any leaked blocks
292 */
293 void DMem_ReportLeaks() {
294 MemoryListLink * link;
295
296 DMutex_Enter(DMemMutex);
297
298 /* Force memory leaks to be output regardless of trace settings */
299 DTrace_EnableFile(THIS_FILE, TRUE);
300 DTRACE_PRINTLN("--------------------------");
301 DTRACE_PRINTLN("Debug Memory Manager Leaks");
302 DTRACE_PRINTLN("--------------------------");
303
304 /* walk through allocated list and dump any blocks not marked as freed */
305 link = MemoryList.next;
306 while (link != NULL) {
|
57 struct MemoryListLink * listEnter; /* pointer to the free list node */
58 byte_t guard[MAX_GUARD_BYTES]; /* guard area for underrun check */
59 } MemoryBlockHeader;
60
61 /* Tail to follow allocated block */
62 typedef struct MemoryBlockTail {
63 byte_t guard[MAX_GUARD_BYTES]; /* guard area overrun check */
64 } MemoryBlockTail;
65
66 /* Linked list of allocated memory blocks */
67 typedef struct MemoryListLink {
68 struct MemoryListLink * next;
69 MemoryBlockHeader * header;
70 int freed;
71 } MemoryListLink;
72
73 /**************************************************
74 * Global Data structures
75 */
76 static DMemState DMemGlobalState;
77 extern const DMemState * DMemStatePtr;
78 //Do this to avoid compiler warning about const extern initialization.
79 const DMemState* DMemStatePtr = &DMemGlobalState;
80 static MemoryListLink MemoryList = {NULL,NULL,FALSE};
81 static dmutex_t DMemMutex = NULL;
82
83 /**************************************************/
84
85 /*************************************************
86 * Client callback invocation functions
87 */
88 static void * DMem_ClientAllocate(size_t size) {
89 if (DMemGlobalState.pfnAlloc != NULL) {
90 return (*DMemGlobalState.pfnAlloc)(size);
91 }
92 return malloc(size);
93 }
94
95 static void DMem_ClientFree(void * ptr) {
96 if (DMemGlobalState.pfnFree != NULL) {
97 (*DMemGlobalState.pfnFree)(ptr);
98 }
99 free(ptr);
261
262 DMutex_Enter(DMemMutex);
263 if ( memptr == NULL) {
264 goto Exit;
265 }
266
267 /* get the debug block header preceding the allocated memory */
268 header = DMem_GetHeader(memptr);
269 /* fill memory with recognizable 'freed' value */
270 memset(memptr, ByteFreed, header->size);
271 /* mark block as freed */
272 header->listEnter->freed = TRUE;
273 /* update used memory total */
274 DMemGlobalState.totalHeapUsed -= header->size;
275 Exit:
276 DMutex_Exit(DMemMutex);
277 }
278
279 static void DMem_DumpHeader(MemoryBlockHeader * header) {
280 char report[FILENAME_MAX+MAX_DECIMAL_DIGITS*3+1];
281
282 DMem_VerifyHeader(header);
283 sprintf(report, "file: %s, line %d\n" \
284 "size: %d bytes\n" \
285 "order: %d\n" \
286 "-------",
287 header->filename, (int)header->linenumber, (int)header->size, header->order);
288 DTRACE_PRINTLN(report);
289 }
290
291 /*
292 * Call this function at shutdown time to report any leaked blocks
293 */
294 void DMem_ReportLeaks() {
295 MemoryListLink * link;
296
297 DMutex_Enter(DMemMutex);
298
299 /* Force memory leaks to be output regardless of trace settings */
300 DTrace_EnableFile(THIS_FILE, TRUE);
301 DTRACE_PRINTLN("--------------------------");
302 DTRACE_PRINTLN("Debug Memory Manager Leaks");
303 DTRACE_PRINTLN("--------------------------");
304
305 /* walk through allocated list and dump any blocks not marked as freed */
306 link = MemoryList.next;
307 while (link != NULL) {
|