Commit | Line | Data |
---|---|---|
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 | ||
22 | static int malloc_need_init = 1; | |
23 | ||
24 | typedef struct { | |
25 | void* point; | |
26 | size_t size; | |
27 | char comm[MAXDESC]; | |
28 | } malloc_entry; | |
29 | ||
30 | malloc_entry malloc_pointers[MAXMAL]; | |
31 | ||
32 | /* | |
33 | #define mymalloc(x) (mymalloc_file_line(x,__FILE__,__LINE__)) | |
34 | */ | |
35 | ||
36 | ||
37 | void | |
38 | malloc_state() { | |
39 | int i, total; | |
40 | total=0; | |
41 | mm_log((0,"malloc_state()\n")); | |
42 | bndcheck_all(); | |
43 | for(i=0;i<MAXMAL;i++) if (malloc_pointers[i].point!=NULL) { | |
44 | mm_log((0,"%d: %d (0x%x) : %s\n",i,malloc_pointers[i].size,malloc_pointers[i].point,malloc_pointers[i].comm)); | |
45 | total+=malloc_pointers[i].size; | |
46 | } | |
47 | if (total==0 ) mm_log((0,"No memory currently used!\n")) | |
48 | else mm_log((0,"total: %d\n",total)); | |
49 | } | |
50 | ||
51 | ||
52 | void* | |
53 | mymalloc_file_line(int size, char* file, int line) { | |
54 | char *buf; | |
55 | int i; | |
56 | if (malloc_need_init) { | |
57 | for(i=0; i<MAXMAL; i++) malloc_pointers[i].point = NULL; | |
a743c0a6 | 58 | malloc_need_init = 0; |
02d1d628 AMH |
59 | atexit(malloc_state); |
60 | } | |
61 | ||
62 | /* bndcheck_all(); ACTIVATE FOR LOTS OF THRASHING */ | |
63 | ||
64 | if ( (buf = malloc(size+UNDRRNVAL+OVERRNVAL)) == NULL ) { mm_log((1,"Unable to allocate %i for %s (%i)\n", size, file, line)); exit(3); } | |
65 | memset( buf, PADBYTE, UNDRRNVAL ); | |
66 | memset( &buf[UNDRRNVAL+size], PADBYTE, OVERRNVAL ); | |
67 | ||
68 | mm_log((1,"mymalloc_file_line: real address %p\n", buf)); | |
69 | buf += UNDRRNVAL; /* Do this now so we will see the returned address in the logs. */ | |
70 | ||
71 | for(i=0;i<MAXMAL;i++) if (malloc_pointers[i].point == NULL) { | |
72 | malloc_pointers[i].size = size; | |
73 | sprintf(malloc_pointers[i].comm,"%s (%d)", file, line); | |
74 | malloc_pointers[i].point = buf; | |
75 | mm_log((1,"mymalloc_file_line: slot <%d> %d bytes allocated at %p for %s (%d)\n", i, size, buf, file, line)); | |
76 | return buf; | |
77 | } | |
78 | ||
79 | mm_log((0,"more than %d segments allocated at %s (%d)\n", MAXMAL, file, line)); | |
80 | exit(255); | |
81 | return NULL; | |
82 | } | |
83 | ||
84 | ||
85 | ||
86 | ||
87 | /* This function not maintained for now */ | |
88 | ||
89 | /* | |
90 | void* | |
91 | mymalloc_comm(int size,char *comm) { | |
92 | void *buf; | |
93 | int i; | |
94 | if (malloc_need_init) { | |
95 | for(i=0;i<MAXMAL;i++) malloc_pointers[i].point=NULL; | |
96 | malloc_need_init=0; | |
97 | } | |
98 | ||
99 | if ((buf=malloc(size))==NULL) { mm_log((1,"Unable to malloc.\n")); exit(3); } | |
100 | ||
101 | for(i=0;i<MAXMAL;i++) if (malloc_pointers[i].point==NULL) { | |
102 | malloc_pointers[i].point=buf; | |
103 | malloc_pointers[i].size=size; | |
104 | strncpy(malloc_pointers[i].comm,comm,MAXDESC-1); | |
105 | return buf; | |
106 | } | |
107 | mm_log((0,"more than %d segments malloced\n",MAXMAL)); | |
108 | exit(255); | |
109 | return NULL; | |
110 | } | |
111 | */ | |
112 | ||
113 | static | |
114 | void | |
115 | bndcheck(int idx) { | |
116 | int i; | |
117 | size_t s = malloc_pointers[idx].size; | |
118 | unsigned char *pp = malloc_pointers[idx].point; | |
119 | if (!pp) { | |
120 | mm_log((1, "bndcheck: No pointer in slot %d\n", idx)); | |
121 | return; | |
122 | } | |
123 | ||
124 | for(i=0;i<UNDRRNVAL;i++) | |
125 | if (pp[-(1+i)] != PADBYTE) | |
126 | mm_log((1,"bndcheck: UNDERRUN OF %d bytes detected: slot = %d, point = %p, size = %d\n", i+1, idx, pp, s )); | |
127 | ||
128 | for(i=0;i<OVERRNVAL;i++) | |
129 | if (pp[s+i] != PADBYTE) | |
130 | mm_log((1,"bndcheck: OVERRUN OF %d bytes detected: slot = %d, point = %p, size = %d\n", i+1, idx, pp, s )); | |
131 | } | |
132 | ||
133 | void | |
134 | bndcheck_all() { | |
135 | int idx; | |
136 | mm_log((1, "bndcheck_all()\n")); | |
137 | for(idx=0; idx<MAXMAL; idx++) | |
138 | if (malloc_pointers[idx].point) | |
139 | bndcheck(idx); | |
140 | } | |
141 | ||
142 | ||
143 | ||
144 | ||
145 | ||
146 | void | |
147 | myfree_file_line(void *p, char *file, int line) { | |
148 | char *pp = p; | |
149 | int match = 0; | |
150 | int i; | |
151 | ||
152 | for(i=0; i<MAXMAL; i++) if (malloc_pointers[i].point == p) { | |
153 | mm_log((1,"myfree_file_line: pointer %i (%s) freed at %s (%i)\n", i, malloc_pointers[i].comm, file, line)); | |
154 | bndcheck(i); | |
155 | malloc_pointers[i].point = NULL; | |
156 | match++; | |
157 | } | |
158 | ||
159 | if (match != 1) { | |
a743c0a6 | 160 | mm_log((1, "myfree_file_line: INCONSISTENT REFCOUNT %d\n", match)); |
02d1d628 AMH |
161 | } |
162 | ||
163 | mm_log((1, "myfree_file_line: freeing address %p\n", pp-UNDRRNVAL)); | |
164 | ||
165 | free(pp-UNDRRNVAL); | |
166 | } | |
167 | ||
168 | #else | |
169 | ||
170 | #define malloc_comm(a,b) (mymalloc(a)) | |
171 | ||
172 | void | |
173 | malloc_state() { | |
174 | printf("malloc_state: not in debug mode\n"); | |
175 | } | |
176 | ||
177 | void* | |
178 | mymalloc(int size) { | |
179 | void *buf; | |
180 | ||
181 | mm_log((1, "mymalloc(size %d)\n", size)); | |
a743c0a6 | 182 | if ( (buf = malloc(size)) == NULL ) { |
faa9b3e7 | 183 | mm_log((1, "mymalloc: unable to malloc %d\n", size)); |
02d1d628 AMH |
184 | fprintf(stderr,"Unable to malloc.\n"); exit(3); |
185 | } | |
186 | return buf; | |
187 | } | |
188 | ||
189 | void | |
190 | myfree(void *p) { | |
dd55acc8 | 191 | mm_log((1, "myfree(p %p)\n", p)); |
02d1d628 AMH |
192 | free(p); |
193 | } | |
194 | ||
faa9b3e7 TC |
195 | void * |
196 | myrealloc(void *block, size_t size) { | |
197 | void *result; | |
198 | ||
199 | mm_log((1, "myrealloc(block %p, size %u)\n", block, size)); | |
200 | if ((result = realloc(block, size)) == NULL) { | |
201 | mm_log((1, "myrealloc: out of memory\n")); | |
202 | fprintf(stderr, "Out of memory.\n"); | |
203 | exit(3); | |
204 | } | |
205 | return result; | |
206 | } | |
207 | ||
02d1d628 AMH |
208 | #endif /* IMAGER_MALLOC_DEBUG */ |
209 | ||
210 | ||
211 | ||
212 | ||
213 | ||
214 | ||
215 | ||
216 | ||
217 | #undef min | |
218 | #undef max | |
219 | ||
220 | int | |
221 | min(int a,int b) { | |
222 | if (a<b) return a; else return b; | |
223 | } | |
224 | ||
225 | int | |
226 | max(int a,int b) { | |
227 | if (a>b) return a; else return b; | |
228 | } | |
229 | ||
230 | int | |
231 | myread(int fd,void *buf,int len) { | |
232 | unsigned char* bufc; | |
233 | int bc,rc; | |
234 | bufc = (unsigned char*)buf; | |
235 | bc=0; | |
236 | while( ((rc=read(fd,bufc+bc,len-bc))>0 ) && (bc!=len) ) bc+=rc; | |
237 | if ( rc < 0 ) return rc; | |
238 | else return bc; | |
239 | } | |
240 | ||
241 | int | |
242 | mywrite(int fd,void *buf,int len) { | |
243 | unsigned char* bufc; | |
244 | int bc,rc; | |
245 | bufc=(unsigned char*)buf; | |
246 | bc=0; | |
247 | while(((rc=write(fd,bufc+bc,len-bc))>0) && (bc!=len)) bc+=rc; | |
248 | if (rc<0) return rc; | |
249 | else return bc; | |
250 | } | |
251 | ||
252 | void | |
253 | interleave(unsigned char *inbuffer,unsigned char *outbuffer,int rowsize,int channels) { | |
254 | int ch,ind,i; | |
255 | i=0; | |
256 | if ( inbuffer==outbuffer ) return; /* Check if data is already in interleaved format */ | |
257 | for( ind=0; ind<rowsize; ind++) for (ch=0; ch<channels; ch++) outbuffer[i++] = inbuffer[rowsize*ch+ind]; | |
258 | } | |
259 | ||
260 |