diff options
author | otto <> | 2011-05-08 07:08:13 +0000 |
---|---|---|
committer | otto <> | 2011-05-08 07:08:13 +0000 |
commit | 245579a6674cf45b87ca39127330004e8da22f80 (patch) | |
tree | 79be0af16600f42ed3e2d5aa79a08eac8467ea62 | |
parent | daa41feed7a1d73dfc71d8d7a287a7f1db625be9 (diff) | |
download | openbsd-245579a6674cf45b87ca39127330004e8da22f80.tar.gz openbsd-245579a6674cf45b87ca39127330004e8da22f80.tar.bz2 openbsd-245579a6674cf45b87ca39127330004e8da22f80.zip |
Move MALLOC_STATS code to bottom of file, so the real stuff is more at the top.
-rw-r--r-- | src/lib/libc/stdlib/malloc.c | 278 |
1 files changed, 141 insertions, 137 deletions
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c index 0d1b2290be..025508a335 100644 --- a/src/lib/libc/stdlib/malloc.c +++ b/src/lib/libc/stdlib/malloc.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: malloc.c,v 1.130 2011/05/05 12:11:20 otto Exp $ */ | 1 | /* $OpenBSD: malloc.c,v 1.131 2011/05/08 07:08:13 otto Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net> | 3 | * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net> |
4 | * | 4 | * |
@@ -192,6 +192,11 @@ static u_char getrnibble(void); | |||
192 | 192 | ||
193 | extern char *__progname; | 193 | extern char *__progname; |
194 | 194 | ||
195 | #ifdef MALLOC_STATS | ||
196 | void malloc_dump(int); | ||
197 | static void malloc_exit(void); | ||
198 | #endif | ||
199 | |||
195 | /* low bits of r->p determine size: 0 means >= page size and p->size holding | 200 | /* low bits of r->p determine size: 0 means >= page size and p->size holding |
196 | * real size, otherwise r->size is a shift count, or 1 for malloc(0) | 201 | * real size, otherwise r->size is a shift count, or 1 for malloc(0) |
197 | */ | 202 | */ |
@@ -217,142 +222,6 @@ hash(void *p) | |||
217 | return sum; | 222 | return sum; |
218 | } | 223 | } |
219 | 224 | ||
220 | #ifdef MALLOC_STATS | ||
221 | static void | ||
222 | dump_chunk(int fd, struct chunk_info *p, int fromfreelist) | ||
223 | { | ||
224 | char buf[64]; | ||
225 | |||
226 | while (p != NULL) { | ||
227 | snprintf(buf, sizeof(buf), "chunk %d %d/%d %p\n", p->size, | ||
228 | p->free, p->total, p->page); | ||
229 | write(fd, buf, strlen(buf)); | ||
230 | if (!fromfreelist) | ||
231 | break; | ||
232 | p = LIST_NEXT(p, entries); | ||
233 | if (p != NULL) { | ||
234 | snprintf(buf, sizeof(buf), " "); | ||
235 | write(fd, buf, strlen(buf)); | ||
236 | } | ||
237 | } | ||
238 | } | ||
239 | |||
240 | static void | ||
241 | dump_free_chunk_info(int fd, struct dir_info *d) | ||
242 | { | ||
243 | char buf[64]; | ||
244 | int i; | ||
245 | |||
246 | snprintf(buf, sizeof(buf), "Free chunk structs:\n"); | ||
247 | write(fd, buf, strlen(buf)); | ||
248 | for (i = 0; i < MALLOC_MAXSHIFT; i++) { | ||
249 | struct chunk_info *p = LIST_FIRST(&d->chunk_dir[i]); | ||
250 | if (p != NULL) { | ||
251 | snprintf(buf, sizeof(buf), "%2d) ", i); | ||
252 | write(fd, buf, strlen(buf)); | ||
253 | dump_chunk(fd, p, 1); | ||
254 | } | ||
255 | } | ||
256 | |||
257 | } | ||
258 | |||
259 | static void | ||
260 | dump_free_page_info(int fd, struct dir_info *d) | ||
261 | { | ||
262 | char buf[64]; | ||
263 | int i; | ||
264 | |||
265 | snprintf(buf, sizeof(buf), "Free pages cached: %zu\n", | ||
266 | d->free_regions_size); | ||
267 | write(fd, buf, strlen(buf)); | ||
268 | for (i = 0; i < mopts.malloc_cache; i++) { | ||
269 | if (d->free_regions[i].p != NULL) { | ||
270 | snprintf(buf, sizeof(buf), "%2d) ", i); | ||
271 | write(fd, buf, strlen(buf)); | ||
272 | snprintf(buf, sizeof(buf), "free at %p: %zu\n", | ||
273 | d->free_regions[i].p, d->free_regions[i].size); | ||
274 | write(fd, buf, strlen(buf)); | ||
275 | } | ||
276 | } | ||
277 | } | ||
278 | |||
279 | static void | ||
280 | malloc_dump1(int fd, struct dir_info *d) | ||
281 | { | ||
282 | char buf[64]; | ||
283 | size_t i, realsize; | ||
284 | |||
285 | snprintf(buf, sizeof(buf), "Malloc dir of %s at %p\n", __progname, d); | ||
286 | write(fd, buf, strlen(buf)); | ||
287 | if (d == NULL) | ||
288 | return; | ||
289 | snprintf(buf, sizeof(buf), "Regions slots %zu\n", d->regions_total); | ||
290 | write(fd, buf, strlen(buf)); | ||
291 | snprintf(buf, sizeof(buf), "Finds %zu/%zu %f\n", d->finds, | ||
292 | d->find_collisions, | ||
293 | 1.0 + (double)d->find_collisions / d->finds); | ||
294 | write(fd, buf, strlen(buf)); | ||
295 | snprintf(buf, sizeof(buf), "Inserts %zu/%zu %f\n", d->inserts, | ||
296 | d->insert_collisions, | ||
297 | 1.0 + (double)d->insert_collisions / d->inserts); | ||
298 | write(fd, buf, strlen(buf)); | ||
299 | snprintf(buf, sizeof(buf), "Deletes %zu/%zu\n", d->deletes, | ||
300 | d->delete_moves); | ||
301 | write(fd, buf, strlen(buf)); | ||
302 | snprintf(buf, sizeof(buf), "Cheap reallocs %zu/%zu\n", | ||
303 | d->cheap_reallocs, d->cheap_realloc_tries); | ||
304 | write(fd, buf, strlen(buf)); | ||
305 | snprintf(buf, sizeof(buf), "Regions slots free %zu\n", d->regions_free); | ||
306 | write(fd, buf, strlen(buf)); | ||
307 | for (i = 0; i < d->regions_total; i++) { | ||
308 | if (d->r[i].p != NULL) { | ||
309 | size_t h = hash(d->r[i].p) & | ||
310 | (d->regions_total - 1); | ||
311 | snprintf(buf, sizeof(buf), "%4zx) #%zx %zd ", | ||
312 | i, h, h - i); | ||
313 | write(fd, buf, strlen(buf)); | ||
314 | REALSIZE(realsize, &d->r[i]); | ||
315 | if (realsize > MALLOC_MAXCHUNK) { | ||
316 | snprintf(buf, sizeof(buf), | ||
317 | "%p: %zu\n", d->r[i].p, realsize); | ||
318 | write(fd, buf, strlen(buf)); | ||
319 | } else | ||
320 | dump_chunk(fd, | ||
321 | (struct chunk_info *)d->r[i].size, 0); | ||
322 | } | ||
323 | } | ||
324 | dump_free_chunk_info(fd, d); | ||
325 | dump_free_page_info(fd, d); | ||
326 | snprintf(buf, sizeof(buf), "In use %zu\n", malloc_used); | ||
327 | write(fd, buf, strlen(buf)); | ||
328 | snprintf(buf, sizeof(buf), "Guarded %zu\n", malloc_guarded); | ||
329 | write(fd, buf, strlen(buf)); | ||
330 | } | ||
331 | |||
332 | |||
333 | void | ||
334 | malloc_dump(int fd) | ||
335 | { | ||
336 | malloc_dump1(fd, g_pool); | ||
337 | } | ||
338 | |||
339 | static void | ||
340 | malloc_exit(void) | ||
341 | { | ||
342 | static const char q[] = "malloc() warning: Couldn't dump stats\n"; | ||
343 | int save_errno = errno, fd; | ||
344 | |||
345 | fd = open("malloc.out", O_RDWR|O_APPEND); | ||
346 | if (fd != -1) { | ||
347 | malloc_dump(fd); | ||
348 | close(fd); | ||
349 | } else | ||
350 | write(STDERR_FILENO, q, sizeof(q) - 1); | ||
351 | errno = save_errno; | ||
352 | } | ||
353 | #endif /* MALLOC_STATS */ | ||
354 | |||
355 | |||
356 | static void | 225 | static void |
357 | wrterror(char *msg, void *p) | 226 | wrterror(char *msg, void *p) |
358 | { | 227 | { |
@@ -1516,3 +1385,138 @@ posix_memalign(void **memptr, size_t alignment, size_t size) | |||
1516 | return 0; | 1385 | return 0; |
1517 | } | 1386 | } |
1518 | 1387 | ||
1388 | #ifdef MALLOC_STATS | ||
1389 | static void | ||
1390 | dump_chunk(int fd, struct chunk_info *p, int fromfreelist) | ||
1391 | { | ||
1392 | char buf[64]; | ||
1393 | |||
1394 | while (p != NULL) { | ||
1395 | snprintf(buf, sizeof(buf), "chunk %d %d/%d %p\n", p->size, | ||
1396 | p->free, p->total, p->page); | ||
1397 | write(fd, buf, strlen(buf)); | ||
1398 | if (!fromfreelist) | ||
1399 | break; | ||
1400 | p = LIST_NEXT(p, entries); | ||
1401 | if (p != NULL) { | ||
1402 | snprintf(buf, sizeof(buf), " "); | ||
1403 | write(fd, buf, strlen(buf)); | ||
1404 | } | ||
1405 | } | ||
1406 | } | ||
1407 | |||
1408 | static void | ||
1409 | dump_free_chunk_info(int fd, struct dir_info *d) | ||
1410 | { | ||
1411 | char buf[64]; | ||
1412 | int i; | ||
1413 | |||
1414 | snprintf(buf, sizeof(buf), "Free chunk structs:\n"); | ||
1415 | write(fd, buf, strlen(buf)); | ||
1416 | for (i = 0; i < MALLOC_MAXSHIFT; i++) { | ||
1417 | struct chunk_info *p = LIST_FIRST(&d->chunk_dir[i]); | ||
1418 | if (p != NULL) { | ||
1419 | snprintf(buf, sizeof(buf), "%2d) ", i); | ||
1420 | write(fd, buf, strlen(buf)); | ||
1421 | dump_chunk(fd, p, 1); | ||
1422 | } | ||
1423 | } | ||
1424 | |||
1425 | } | ||
1426 | |||
1427 | static void | ||
1428 | dump_free_page_info(int fd, struct dir_info *d) | ||
1429 | { | ||
1430 | char buf[64]; | ||
1431 | int i; | ||
1432 | |||
1433 | snprintf(buf, sizeof(buf), "Free pages cached: %zu\n", | ||
1434 | d->free_regions_size); | ||
1435 | write(fd, buf, strlen(buf)); | ||
1436 | for (i = 0; i < mopts.malloc_cache; i++) { | ||
1437 | if (d->free_regions[i].p != NULL) { | ||
1438 | snprintf(buf, sizeof(buf), "%2d) ", i); | ||
1439 | write(fd, buf, strlen(buf)); | ||
1440 | snprintf(buf, sizeof(buf), "free at %p: %zu\n", | ||
1441 | d->free_regions[i].p, d->free_regions[i].size); | ||
1442 | write(fd, buf, strlen(buf)); | ||
1443 | } | ||
1444 | } | ||
1445 | } | ||
1446 | |||
1447 | static void | ||
1448 | malloc_dump1(int fd, struct dir_info *d) | ||
1449 | { | ||
1450 | char buf[64]; | ||
1451 | size_t i, realsize; | ||
1452 | |||
1453 | snprintf(buf, sizeof(buf), "Malloc dir of %s at %p\n", __progname, d); | ||
1454 | write(fd, buf, strlen(buf)); | ||
1455 | if (d == NULL) | ||
1456 | return; | ||
1457 | snprintf(buf, sizeof(buf), "Regions slots %zu\n", d->regions_total); | ||
1458 | write(fd, buf, strlen(buf)); | ||
1459 | snprintf(buf, sizeof(buf), "Finds %zu/%zu %f\n", d->finds, | ||
1460 | d->find_collisions, | ||
1461 | 1.0 + (double)d->find_collisions / d->finds); | ||
1462 | write(fd, buf, strlen(buf)); | ||
1463 | snprintf(buf, sizeof(buf), "Inserts %zu/%zu %f\n", d->inserts, | ||
1464 | d->insert_collisions, | ||
1465 | 1.0 + (double)d->insert_collisions / d->inserts); | ||
1466 | write(fd, buf, strlen(buf)); | ||
1467 | snprintf(buf, sizeof(buf), "Deletes %zu/%zu\n", d->deletes, | ||
1468 | d->delete_moves); | ||
1469 | write(fd, buf, strlen(buf)); | ||
1470 | snprintf(buf, sizeof(buf), "Cheap reallocs %zu/%zu\n", | ||
1471 | d->cheap_reallocs, d->cheap_realloc_tries); | ||
1472 | write(fd, buf, strlen(buf)); | ||
1473 | snprintf(buf, sizeof(buf), "Regions slots free %zu\n", d->regions_free); | ||
1474 | write(fd, buf, strlen(buf)); | ||
1475 | for (i = 0; i < d->regions_total; i++) { | ||
1476 | if (d->r[i].p != NULL) { | ||
1477 | size_t h = hash(d->r[i].p) & | ||
1478 | (d->regions_total - 1); | ||
1479 | snprintf(buf, sizeof(buf), "%4zx) #%zx %zd ", | ||
1480 | i, h, h - i); | ||
1481 | write(fd, buf, strlen(buf)); | ||
1482 | REALSIZE(realsize, &d->r[i]); | ||
1483 | if (realsize > MALLOC_MAXCHUNK) { | ||
1484 | snprintf(buf, sizeof(buf), | ||
1485 | "%p: %zu\n", d->r[i].p, realsize); | ||
1486 | write(fd, buf, strlen(buf)); | ||
1487 | } else | ||
1488 | dump_chunk(fd, | ||
1489 | (struct chunk_info *)d->r[i].size, 0); | ||
1490 | } | ||
1491 | } | ||
1492 | dump_free_chunk_info(fd, d); | ||
1493 | dump_free_page_info(fd, d); | ||
1494 | snprintf(buf, sizeof(buf), "In use %zu\n", malloc_used); | ||
1495 | write(fd, buf, strlen(buf)); | ||
1496 | snprintf(buf, sizeof(buf), "Guarded %zu\n", malloc_guarded); | ||
1497 | write(fd, buf, strlen(buf)); | ||
1498 | } | ||
1499 | |||
1500 | |||
1501 | void | ||
1502 | malloc_dump(int fd) | ||
1503 | { | ||
1504 | malloc_dump1(fd, g_pool); | ||
1505 | } | ||
1506 | |||
1507 | static void | ||
1508 | malloc_exit(void) | ||
1509 | { | ||
1510 | static const char q[] = "malloc() warning: Couldn't dump stats\n"; | ||
1511 | int save_errno = errno, fd; | ||
1512 | |||
1513 | fd = open("malloc.out", O_RDWR|O_APPEND); | ||
1514 | if (fd != -1) { | ||
1515 | malloc_dump(fd); | ||
1516 | close(fd); | ||
1517 | } else | ||
1518 | write(STDERR_FILENO, q, sizeof(q) - 1); | ||
1519 | errno = save_errno; | ||
1520 | } | ||
1521 | |||
1522 | #endif /* MALLOC_STATS */ | ||