2 * Copyright (c) 2005 Massachusetts Institute of Technology
\r
4 * Permission is hereby granted, free of charge, to any person
\r
5 * obtaining a copy of this software and associated documentation
\r
6 * files (the "Software"), to deal in the Software without
\r
7 * restriction, including without limitation the rights to use, copy,
\r
8 * modify, merge, publish, distribute, sublicense, and/or sell copies
\r
9 * of the Software, and to permit persons to whom the Software is
\r
10 * furnished to do so, subject to the following conditions:
\r
12 * The above copyright notice and this permission notice shall be
\r
13 * included in all copies or substantial portions of the Software.
\r
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\r
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\r
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
\r
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
\r
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
\r
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
\r
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
\r
34 #define HASHSIZE 1151
\r
35 #define ALLOCBLOCK 1024
\r
37 #define HASHPTR(p) (((size_t) (p)) % HASHSIZE)
\r
39 typedef struct tag_allocation {
\r
45 LDCL(struct tag_allocation);
\r
48 static allocation * ht[HASHSIZE];
\r
50 static allocation * next_alloc = NULL;
\r
51 static size_t idx_next_alloc = 0;
\r
52 static allocation * free_alloc = NULL;
\r
54 static CRITICAL_SECTION cs_alloc;
\r
55 static LONG ctr = 0;
\r
56 static int perf_ready = 0;
\r
58 static void perf_once(void) {
\r
59 if (InterlockedIncrement(&ctr) == 1) {
\r
60 InitializeCriticalSection(&cs_alloc);
\r
61 ZeroMemory(ht, sizeof(ht));
\r
63 next_alloc = malloc(sizeof(allocation) * ALLOCBLOCK);
\r
70 while(!perf_ready) {
\r
71 Sleep(0); /* relinquish control to the thread
\r
72 that is initializing the alloc
\r
78 static allocation * get_allocation(void) {
\r
81 LPOP(&free_alloc, &a);
\r
83 if (idx_next_alloc == ALLOCBLOCK) {
\r
84 next_alloc = malloc(sizeof(allocation) * ALLOCBLOCK);
\r
89 a = &next_alloc[idx_next_alloc];
\r
96 #define MAXCB_STR 32768
\r
99 perf_wcsdup(char * file, int line, const wchar_t * str) {
\r
103 if (FAILED(StringCbLength(str, MAXCB_STR, &cb)))
\r
105 cb += sizeof(wchar_t);
\r
107 dest = (wchar_t *) perf_malloc(file, line, cb);
\r
108 StringCbCopy(dest, cb, str);
\r
114 perf_strdup(char * file, int line, const char * str) {
\r
118 if (FAILED(StringCbLengthA(str, MAXCB_STR, &cb)))
\r
120 cb += sizeof(char);
\r
122 dest = (char *) perf_malloc(file, line, cb);
\r
123 StringCbCopyA(dest, cb, str);
\r
129 perf_malloc(char * file, int line, size_t s) {
\r
138 EnterCriticalSection(&cs_alloc);
\r
139 a = get_allocation();
\r
143 assert(ptr); /* TODO: handle this gracefully */
\r
145 if (file[0] == '.' && file[1] == '\\')
\r
148 StringCbCopyA(a->file, sizeof(a->file), file);
\r
156 LeaveCriticalSection(&cs_alloc);
\r
162 perf_realloc(char * file, int line, void * data, size_t s) {
\r
168 return perf_malloc(file, line, s);
\r
173 n_data = realloc(data, s);
\r
177 EnterCriticalSection(&cs_alloc);
\r
178 for (a = ht[h]; a; a = LNEXT(a)) {
\r
179 if (a->ptr == data)
\r
185 LDELETE(&ht[h], a);
\r
190 h = HASHPTR(n_data);
\r
192 LeaveCriticalSection(&cs_alloc);
\r
198 perf_free (void * b) {
\r
205 EnterCriticalSection(&cs_alloc);
\r
206 for(a = ht[h]; a; a = LNEXT(a)) {
\r
213 LDELETE(&ht[h], a);
\r
214 LPUSH(&free_alloc, a);
\r
215 LeaveCriticalSection(&cs_alloc);
\r
219 perf_dump(char * file) {
\r
227 EnterCriticalSection(&cs_alloc);
\r
228 f = fopen(file, "w");
\r
232 fprintf(f, "Leaked allocations list ....\n");
\r
233 fprintf(f, "File\tLine\tSize\n");
\r
235 for (i=0; i < HASHSIZE; i++) {
\r
236 for (a = ht[i]; a; a = LNEXT(a)) {
\r
237 fprintf(f, "%s\t%6d\t%6d\n", a->file, a->line, a->size);
\r
242 fprintf(f, "----------------------------------------\n");
\r
243 fprintf(f, "Total\t\t%d\n", total);
\r
244 fprintf(f, "----------------- End ------------------\n");
\r
248 LeaveCriticalSection(&cs_alloc);
\r