/* $Id: ptrinfo.c,v 1.5 2006/09/17 08:51:15 maxim Exp $ * */ #include #include #include #include "configure.h" #include "settings.h" #include "ptrinfo.h" #include "str.h" #include "misc.h" #if DEBUGLOG #define MIN_ALLOC 256 typedef struct PtrInfo_ { void* ptr; int size; char* file; int line; } PtrInfo; typedef struct PtrInfos_ { PtrInfo* ptrs; int count; } PtrInfos; static PtrInfos ptrs; static unsigned allocated = 0; void addPtr(void* ptr, int size, char* file, int line) { int start = 0; int midd = 0; int end = ptrs.count; int res = 0; debug("addPtr(%p, %d, %s:%d)", ptr, size, file, line); if (end && ptr <= ptrs.ptrs[end - 1].ptr) { while (start < end) { PtrInfo* pp; midd = (start + end) >> 1; pp = &(ptrs.ptrs[midd]); if (ptr == pp->ptr) { message(ERROR, "strange: already have ptr %p (%d bytes, %s:%d)", pp->ptr, pp->size, pp->file, pp->line); return; } if (ptr < pp->ptr) { end = midd; res = 0; } else { start = midd + 1; res = 1; } } } else { midd = end; } midd += res; if (!ptrs.count) { ptrs.ptrs = malloc(sizeof(PtrInfo) * MIN_ALLOC); if (!ptrs.ptrs) return; } else if (ptrs.count >= MIN_ALLOC && !(ptrs.count & (ptrs.count - 1))) { debug("allocated %d bytes, %d pointers", allocated, ptrs.count); ptrs.ptrs = realloc(ptrs.ptrs, sizeof(PtrInfo) * (ptrs.count * 2)); if (!ptrs.ptrs) return; } if (ptrs.count != midd) memmove(&(ptrs.ptrs[midd+1]), &(ptrs.ptrs[midd]), (ptrs.count-midd)*sizeof(PtrInfo)); ptrs.ptrs[midd].ptr = ptr; ptrs.ptrs[midd].size = size; ptrs.ptrs[midd].file = file; ptrs.ptrs[midd].line = line; allocated += size; ptrs.count++; } void delPtr(void* ptr, char* file, int line) { int start = 0; int midd = 0; int end = ptrs.count; debug("delPtr(%p, %s:%d)", ptr, file, line); if (!ptrs.count) { message(ERROR, "strange: nothing is allocated, but free is called for %p at %s:%d)", ptr, file, line); return; } if (ptr != ptrs.ptrs[end - 1].ptr) { while (start < end) { PtrInfo* pp; midd = (start + end) >> 1; pp = &(ptrs.ptrs[midd]); if (ptr == pp->ptr) goto found; if (ptr < pp->ptr) end = midd; else start = midd + 1; } } else { midd = end - 1; goto found; } message(ERROR, "strange: freed ptr is not found: %p (%s:%d)", ptr, file, line); return; found: allocated -= ptrs.ptrs[midd].size; ptrs.count--; if (midd != ptrs.count) memmove(&(ptrs.ptrs[midd]), &(ptrs.ptrs[midd + 1]), sizeof(PtrInfo) * (ptrs.count - midd)); if (ptrs.count) { if (biRound(ptrs.count + 1, MIN_ALLOC) != biRound(ptrs.count, MIN_ALLOC)) ptrs.ptrs = realloc(ptrs.ptrs, sizeof(PtrInfo) * biRound(ptrs.count, MIN_ALLOC)); } else { free(ptrs.ptrs); ptrs.ptrs = NULL; } } void showPtrs(int full) { int i; PtrInfo* p; message(MESSAGE, "Allocated %s bytes, %s pointers", itos(allocated), itos(ptrs.count)); if (!full) return; for (i = 0, p = ptrs.ptrs; i < ptrs.count; i++, p++) { message(MESSAGE, "%p (%d bytes, %s:%d)", p->ptr, p->size, p->file, p->line); } } #endif