]>
Commit | Line | Data |
---|---|---|
1c79356b A |
1 | #ifdef DEBUG |
2 | static void print_region_list(void); | |
3 | static int check_block_list(queue_entry * block_list, malloc_block * new_block); | |
d7e50217 | 4 | #endif /* DEBUG */ |
1c79356b A |
5 | |
6 | ||
7 | void print_region_list(void) { | |
8 | unsigned int i; | |
9 | malloc_region * cur_region; | |
10 | ||
11 | cur_region = (malloc_region *)&malloc_region_list; | |
12 | printf("First region:\n"); | |
13 | printf("curr: 0x%8x prev: 0x%8x next: 0x%8x\n", | |
14 | (unsigned int)cur_region, | |
15 | (unsigned int)(cur_region->links.prev), | |
16 | (unsigned int)(cur_region->links.next)); | |
17 | ||
18 | printf("Region list contents:\n"); | |
19 | ||
20 | i = 0; | |
21 | queue_iterate(&malloc_region_list, cur_region, malloc_region *, links) { | |
22 | if (i > num_regions) { | |
23 | break; | |
24 | } | |
25 | printf("curr: 0x%8x prev: 0x%8x next: 0x%8x\n", | |
26 | (unsigned int)cur_region, | |
27 | (unsigned int)(cur_region->links.prev), | |
28 | (unsigned int)(cur_region->links.next)); | |
29 | i++; | |
30 | } | |
31 | return; | |
32 | } | |
33 | ||
34 | void print_block_list(queue_entry * block_list) { | |
35 | malloc_block * cur_block; | |
36 | ||
37 | queue_iterate(block_list, cur_block, malloc_block *, links) { | |
38 | printf("curr: 0x%8x prev: 0x%8x next: 0x%8x\n", | |
39 | (unsigned int)cur_block, | |
40 | (unsigned int)(cur_block->links.prev), | |
41 | (unsigned int)(cur_block->links.next)); | |
42 | } | |
43 | return; | |
44 | } | |
45 | ||
46 | int break_here(void) { | |
47 | return 0; | |
48 | } | |
49 | ||
50 | ||
51 | int check_block_list(queue_entry * block_list, malloc_block * new_block) { | |
52 | void * end_of_new_block; | |
53 | malloc_block * cur_block; | |
54 | unsigned int i = 0; | |
55 | ||
56 | end_of_new_block = new_block + sizeof(malloc_block); | |
57 | ||
58 | queue_iterate(block_list, cur_block, malloc_block *, links) { | |
59 | malloc_region * cur_region; | |
60 | void * end_of_region; | |
61 | void * scratch_block; | |
62 | void * end_of_block; | |
63 | ||
64 | cur_region = cur_block->region; | |
65 | end_of_region = cur_region + cur_region->region_size; | |
66 | scratch_block = cur_block; | |
67 | end_of_block = scratch_block + sizeof(malloc_block); | |
68 | ||
69 | if ( ((void *)new_block >= scratch_block && (void *)new_block <= end_of_block) || | |
70 | (end_of_new_block >= scratch_block && end_of_new_block <= end_of_block) || | |
71 | (scratch_block >= (void *)new_block && scratch_block <= end_of_new_block) || | |
72 | (end_of_block >= (void *)new_block && end_of_block <= end_of_new_block) ) { | |
73 | ||
74 | printf("New block %p overlaps existing block %p.\n", | |
75 | new_block, scratch_block); | |
76 | break_here(); | |
77 | exit(1); | |
78 | return 1; | |
79 | ||
80 | } | |
81 | ||
82 | if (scratch_block < (void *)cur_region || | |
83 | end_of_block >= end_of_region) { | |
84 | ||
85 | printf("Found invalid block link at block %d.\n", i); | |
86 | printf("curr: 0x%8x prev: 0x%8x next: 0x%8x\n", | |
87 | (unsigned int)cur_block, | |
88 | (unsigned int)(cur_block->links.prev), | |
89 | (unsigned int)(cur_block->links.next)); | |
90 | break_here(); | |
91 | exit(1); | |
92 | return 1; | |
93 | } | |
94 | ||
95 | scratch_block = (malloc_block *)cur_block->links.prev; | |
96 | end_of_block = scratch_block + sizeof(malloc_block); | |
97 | ||
98 | if (scratch_block < (void *)cur_region || | |
99 | end_of_block >= end_of_region) { | |
100 | ||
101 | printf("Found invalid block link at block %d.\n", i); | |
102 | printf("curr: 0x%8x prev: 0x%8x next: 0x%8x\n", | |
103 | (unsigned int)cur_block, | |
104 | (unsigned int)(cur_block->links.prev), | |
105 | (unsigned int)(cur_block->links.next)); | |
106 | break_here(); | |
107 | exit(1); | |
108 | return 1; | |
109 | } | |
110 | ||
111 | scratch_block = (malloc_block *)cur_block->links.next; | |
112 | end_of_block = scratch_block + sizeof(malloc_block); | |
113 | ||
114 | if (scratch_block < (void *)cur_region || | |
115 | end_of_block >= end_of_region) { | |
116 | printf("Found invalid block link at block %d.\n", i); | |
117 | ||
118 | printf("curr: 0x%8x prev: 0x%8x next: 0x%8x\n", | |
119 | (unsigned int)cur_block, | |
120 | (unsigned int)(cur_block->links.prev), | |
121 | (unsigned int)(cur_block->links.next)); | |
122 | break_here(); | |
123 | exit(1); | |
124 | return 1; | |
125 | } | |
126 | ||
127 | i++; | |
128 | } | |
129 | return 0; | |
130 | } | |
131 | ||
132 | ||
133 | int malloc_sanity_check(void) { | |
134 | unsigned int i; | |
135 | malloc_region * cur_region; | |
136 | ||
137 | i = 0; | |
138 | queue_iterate(&malloc_region_list, cur_region, malloc_region *, links) { | |
139 | if (i > num_regions) { | |
140 | return 0; | |
141 | } | |
142 | if (cur_region->links.next != &malloc_region_list && | |
143 | cur_region->links.next < (queue_entry *)cur_region) { | |
144 | printf("inconsistency detected\n"); | |
145 | return 0; | |
146 | } | |
147 | i++; | |
148 | } | |
149 | return 1; | |
150 | } | |
151 | ||
152 | ||
153 | /********************************************************************* | |
154 | * malloc_hiwat() | |
155 | * | |
156 | * Returns the maximum amount of memory ever reserved by this package. | |
157 | *********************************************************************/ | |
158 | size_t malloc_hiwat() { | |
159 | return malloc_hiwater_mark; | |
160 | } | |
161 | ||
162 | void malloc_clear_hiwat(void) { | |
163 | malloc_hiwater_mark = 0; | |
164 | return; | |
165 | } | |
166 | ||
167 | size_t malloc_current_usage(void) | |
168 | { | |
169 | return current_block_total; | |
170 | } | |
171 | ||
172 | size_t malloc_region_usage(void) { | |
173 | size_t total = 0; | |
174 | malloc_region * cur_region; | |
175 | ||
176 | queue_iterate(&malloc_region_list, cur_region, malloc_region *, links) { | |
177 | total += cur_region->region_size - sizeof(malloc_region); | |
178 | ||
179 | } | |
180 | return total; | |
181 | } | |
182 | ||
183 | ||
184 | double malloc_peak_usage(void) | |
185 | { | |
186 | return peak_usage; | |
187 | } | |
188 | ||
189 | double malloc_min_usage(void) | |
190 | { | |
191 | return min_usage; | |
192 | } | |
193 | ||
194 | size_t malloc_unused(void) { | |
195 | size_t total = 0; | |
196 | malloc_region * cur_region; | |
197 | malloc_block * cur_block; | |
198 | ||
199 | queue_iterate(&malloc_region_list, cur_region, malloc_region *, links) { | |
200 | total += cur_region->free_size; | |
201 | ||
202 | } | |
203 | queue_iterate(&sorted_free_block_list, cur_block, malloc_block *, links) { | |
204 | total += cur_block->block_size; | |
205 | } | |
206 | ||
207 | return total; | |
208 | } | |
209 | ||
210 | double malloc_current_efficiency(void) | |
211 | { | |
212 | double efficiency = 0.0; | |
213 | double total_block_size = 0; | |
214 | double total_request_size = 0; | |
215 | unsigned long total_block_sizeL = 0; | |
216 | unsigned long total_request_sizeL = 0; | |
217 | size_t discrepancy; | |
218 | size_t max_discrepancy = 0; | |
219 | malloc_region * cur_region; | |
220 | malloc_block * cur_block; | |
221 | ||
222 | queue_iterate(&malloc_region_list, cur_region, malloc_region *, links) { | |
223 | queue_iterate(&cur_region->block_list, cur_block, malloc_block *, links) { | |
224 | size_t cur_block_size = cur_block->block_size - sizeof(malloc_block); | |
225 | total_block_sizeL += cur_block_size; | |
226 | total_request_sizeL += cur_block->request_size; | |
227 | total_block_size += (double)cur_block_size; | |
228 | total_request_size += (double)cur_block->request_size; | |
229 | discrepancy = cur_block_size - cur_block->request_size; | |
230 | if (discrepancy > max_discrepancy) { | |
231 | max_discrepancy = discrepancy; | |
232 | } | |
233 | } | |
234 | } | |
235 | ||
236 | if (total_block_size > 0) { | |
237 | efficiency = (double)total_request_size / (double)total_block_size; | |
238 | } else { | |
239 | efficiency = 1.0; | |
240 | } | |
241 | ||
242 | printf("requested %.2f, actual %.2f\n", total_request_size, total_block_size); | |
243 | printf("requested %ld, actual %ld\n", total_request_sizeL, total_block_sizeL); | |
244 | printf("max discrepancy %ld\n", max_discrepancy); | |
245 | ||
246 | return efficiency; | |
247 | } | |
248 | ||
249 | ||
250 | /********************************************************************* | |
251 | * malloc_report() | |
252 | * | |
253 | * Print stats on allocated regions and blocks. | |
254 | *********************************************************************/ | |
255 | void malloc_report(void) { | |
256 | malloc_region * cur_region; | |
257 | malloc_block * cur_block; | |
258 | size_t total_block_size; | |
259 | ||
260 | queue_iterate(&malloc_region_list, cur_region, malloc_region *, links) { | |
261 | ||
262 | printf("VM Region, size, free: "); | |
263 | printf("%p, %d, %d\n", cur_region, | |
264 | cur_region->region_size, | |
265 | cur_region->free_size); | |
266 | ||
267 | total_block_size = 0; | |
268 | ||
269 | queue_iterate(&cur_region->block_list, cur_block, malloc_block *, links) { | |
270 | ||
271 | total_block_size += cur_block->block_size; | |
272 | printf(" Block address, size: %p, %ld (%ld)\n", | |
273 | cur_block->buffer, cur_block->block_size, | |
274 | cur_block->block_size - sizeof(malloc_block)); | |
275 | printf(" Block content: %s\n", | |
276 | (char *)cur_block->buffer); | |
277 | } | |
278 | printf(" Total blocks size: %ld\n", total_block_size); | |
279 | #if 0 | |
280 | queue_iterate(&cur_region->free_list, cur_block, malloc_block *, links) { | |
281 | ||
282 | total_block_size += cur_block->block_size; | |
283 | printf(" Free block address, size: %p, %ld (%ld)\n", | |
284 | cur_block->buffer, cur_block->block_size, | |
285 | cur_block->block_size - sizeof(malloc_block)); | |
286 | } | |
d7e50217 | 287 | #endif /* 0 */ |
1c79356b A |
288 | } |
289 | ||
290 | printf("High water mark: %ld\n", malloc_hiwater_mark); | |
291 | ||
292 | return; | |
293 | } /* malloc_report() */ | |
294 |