release some memory
[imager.git] / io.c
CommitLineData
02d1d628
AMH
1#include "io.h"
2#include <stdlib.h>
3#ifndef _MSC_VER
4#include <unistd.h>
5#endif
6
7
8/* FIXME: make allocation dynamic */
9
10
11#ifdef IMAGER_DEBUG_MALLOC
12
2ff8ed30 13#define MAXMAL 102400
02d1d628
AMH
14#define MAXDESC 65
15
a743c0a6
AMH
16#define UNDRRNVAL 10
17#define OVERRNVAL 10
02d1d628
AMH
18
19#define PADBYTE 0xaa
20
21
22static int malloc_need_init = 1;
23
24typedef struct {
fe6163bf 25 void* ptr;
02d1d628 26 size_t size;
fe6163bf 27 char comm[MAXDESC];
02d1d628
AMH
28} malloc_entry;
29
30malloc_entry malloc_pointers[MAXMAL];
31
fe6163bf
AMH
32
33
34
35/* Utility functions */
36
37
38static
39void
aea697ad 40malloc_init(void) {
fe6163bf
AMH
41 int i;
42 for(i=0; i<MAXMAL; i++) malloc_pointers[i].ptr = NULL;
43 malloc_need_init = 0;
44 atexit(malloc_state);
45}
46
47
48static
49int
50find_ptr(void *p) {
51 int i;
52 for(i=0;i<MAXMAL;i++)
53 if (malloc_pointers[i].ptr == p)
54 return i;
55 return -1;
56}
57
58
59/* Takes a pointer to real start of array,
60 * sets the entries in the table, returns
61 * the offset corrected pointer */
62
63static
64void *
65set_entry(int i, char *buf, size_t size, char *file, int line) {
66 memset( buf, PADBYTE, UNDRRNVAL );
67 memset( &buf[UNDRRNVAL+size], PADBYTE, OVERRNVAL );
68 buf += UNDRRNVAL;
69 malloc_pointers[i].ptr = buf;
70 malloc_pointers[i].size = size;
71 sprintf(malloc_pointers[i].comm,"%s (%d)", file, line);
72 return buf;
73}
74
75
02d1d628
AMH
76
77
78void
aea697ad 79malloc_state(void) {
fe6163bf
AMH
80 int i, total = 0;
81
02d1d628
AMH
82 mm_log((0,"malloc_state()\n"));
83 bndcheck_all();
fe6163bf
AMH
84 for(i=0; i<MAXMAL; i++) if (malloc_pointers[i].ptr != NULL) {
85 mm_log((0,"%d: %d (0x%x) : %s\n", i, malloc_pointers[i].size, malloc_pointers[i].ptr, malloc_pointers[i].comm));
86 total += malloc_pointers[i].size;
02d1d628 87 }
fe6163bf
AMH
88 if (total == 0) mm_log((0,"No memory currently used!\n"))
89 else mm_log((0,"total: %d\n",total));
02d1d628
AMH
90}
91
92
fe6163bf 93
02d1d628 94void*
fe6163bf 95mymalloc_file_line(size_t size, char* file, int line) {
02d1d628
AMH
96 char *buf;
97 int i;
fe6163bf
AMH
98 if (malloc_need_init) malloc_init();
99
100 /* bndcheck_all(); Uncomment for LOTS OF THRASHING */
101
102 if ( (i = find_ptr(NULL)) < 0 ) {
103 mm_log((0,"more than %d segments allocated at %s (%d)\n", MAXMAL, file, line));
104 exit(3);
02d1d628
AMH
105 }
106
fe6163bf
AMH
107 if ( (buf = malloc(size+UNDRRNVAL+OVERRNVAL)) == NULL ) {
108 mm_log((1,"Unable to allocate %i for %s (%i)\n", size, file, line));
109 exit(3);
02d1d628
AMH
110 }
111
fe6163bf
AMH
112 buf = set_entry(i, buf, size, file, line);
113 mm_log((1,"mymalloc_file_line: slot <%d> %d bytes allocated at %p for %s (%d)\n", i, size, buf, file, line));
114 return buf;
02d1d628
AMH
115}
116
117
118
119
02d1d628 120
fe6163bf
AMH
121
122
02d1d628 123void*
fe6163bf
AMH
124myrealloc_file_line(void *ptr, size_t newsize, char* file, int line) {
125 char *buf;
02d1d628 126 int i;
fe6163bf
AMH
127
128 if (malloc_need_init) malloc_init();
129 /* bndcheck_all(); ACTIVATE FOR LOTS OF THRASHING */
130
131 if (!ptr) {
132 mm_log((1, "realloc called with ptr = NULL, sending request to malloc\n"));
133 return mymalloc_file_line(newsize, file, line);
02d1d628
AMH
134 }
135
fe6163bf
AMH
136 if (!newsize) {
137 mm_log((1, "newsize = 0, sending request to free\n"));
138 myfree_file_line(ptr, file, line);
139 return NULL;
140 }
02d1d628 141
fe6163bf
AMH
142 if ( (i = find_ptr(ptr)) == -1) {
143 mm_log((0, "Unable to find %p in realloc for %s (%i)\n", ptr, file, line));
144 exit(3);
145 }
146
aea697ad 147 if ( (buf = realloc(((char *)ptr)-UNDRRNVAL, UNDRRNVAL+OVERRNVAL+newsize)) == NULL ) {
fe6163bf
AMH
148 mm_log((1,"Unable to reallocate %i bytes at %p for %s (%i)\n", newsize, ptr, file, line));
149 exit(3);
02d1d628 150 }
fe6163bf
AMH
151
152 buf = set_entry(i, buf, newsize, file, line);
153 mm_log((1,"realloc_file_line: slot <%d> %d bytes allocated at %p for %s (%d)\n", i, newsize, buf, file, line));
154 return buf;
02d1d628 155}
fe6163bf
AMH
156
157
158
02d1d628
AMH
159
160static
161void
162bndcheck(int idx) {
163 int i;
164 size_t s = malloc_pointers[idx].size;
fe6163bf 165 unsigned char *pp = malloc_pointers[idx].ptr;
02d1d628
AMH
166 if (!pp) {
167 mm_log((1, "bndcheck: No pointer in slot %d\n", idx));
168 return;
169 }
170
171 for(i=0;i<UNDRRNVAL;i++)
fe6163bf
AMH
172 if (pp[-(1+i)] != PADBYTE)
173 mm_log((1,"bndcheck: UNDERRUN OF %d bytes detected: slot = %d, point = %p, size = %d\n", i+1, idx, pp, s ));
02d1d628 174
fe6163bf 175 for(i=0;i<OVERRNVAL;i++)
02d1d628
AMH
176 if (pp[s+i] != PADBYTE)
177 mm_log((1,"bndcheck: OVERRUN OF %d bytes detected: slot = %d, point = %p, size = %d\n", i+1, idx, pp, s ));
178}
179
180void
181bndcheck_all() {
182 int idx;
183 mm_log((1, "bndcheck_all()\n"));
76ff75b8 184 for(idx=0; idx<MAXMAL; idx++)
fe6163bf 185 if (malloc_pointers[idx].ptr)
02d1d628
AMH
186 bndcheck(idx);
187}
188
189
190
191
192
193void
194myfree_file_line(void *p, char *file, int line) {
195 char *pp = p;
196 int match = 0;
197 int i;
198
fe6163bf 199 for(i=0; i<MAXMAL; i++) if (malloc_pointers[i].ptr == p) {
02d1d628
AMH
200 mm_log((1,"myfree_file_line: pointer %i (%s) freed at %s (%i)\n", i, malloc_pointers[i].comm, file, line));
201 bndcheck(i);
fe6163bf 202 malloc_pointers[i].ptr = NULL;
02d1d628
AMH
203 match++;
204 }
205
206 if (match != 1) {
f1ac5027 207 mm_log((1, "myfree_file_line: INCONSISTENT REFCOUNT %d at %s (%i)\n", match, file, line));
aea697ad 208 fprintf(stderr, "myfree_file_line: INCONSISTENT REFCOUNT %d at %s (%i)\n", match, file, line);
a73aeb5f 209 exit(255);
02d1d628
AMH
210 }
211
a73aeb5f 212 mm_log((1, "myfree_file_line: freeing address %p (real %p)\n", pp, pp-UNDRRNVAL));
02d1d628
AMH
213
214 free(pp-UNDRRNVAL);
215}
216
217#else
218
219#define malloc_comm(a,b) (mymalloc(a))
220
221void
222malloc_state() {
223 printf("malloc_state: not in debug mode\n");
224}
225
226void*
227mymalloc(int size) {
228 void *buf;
229
a743c0a6 230 if ( (buf = malloc(size)) == NULL ) {
faa9b3e7 231 mm_log((1, "mymalloc: unable to malloc %d\n", size));
cc6483e0 232 fprintf(stderr,"Unable to malloc %d.\n", size); exit(3);
02d1d628 233 }
f1ac5027 234 mm_log((1, "mymalloc(size %d) -> %p\n", size, buf));
02d1d628
AMH
235 return buf;
236}
237
238void
239myfree(void *p) {
dd55acc8 240 mm_log((1, "myfree(p %p)\n", p));
02d1d628
AMH
241 free(p);
242}
243
faa9b3e7
TC
244void *
245myrealloc(void *block, size_t size) {
246 void *result;
247
248 mm_log((1, "myrealloc(block %p, size %u)\n", block, size));
249 if ((result = realloc(block, size)) == NULL) {
250 mm_log((1, "myrealloc: out of memory\n"));
251 fprintf(stderr, "Out of memory.\n");
252 exit(3);
253 }
254 return result;
255}
256
02d1d628
AMH
257#endif /* IMAGER_MALLOC_DEBUG */
258
259
260
261
262
263
5473b91d 264/* Should these really be here? */
02d1d628
AMH
265
266#undef min
267#undef max
268
269int
270min(int a,int b) {
271 if (a<b) return a; else return b;
272}
273
274int
275max(int a,int b) {
276 if (a>b) return a; else return b;
277}
278