~vcs-imports/eglibc/trunk

« back to all changes in this revision

Viewing changes to libc/malloc/memusagestat.c

  • Committer: joseph
  • Date: 2014-01-03 17:51:28 UTC
  • Revision ID: svn-v4:7b3dc134-2b1b-0410-93df-9e9f96275f8d:trunk:24942
Merge changes between r24468 and r24941 from /fsf/trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* Generate graphic from memory profiling data.
2
 
   Copyright (C) 1998-2013 Free Software Foundation, Inc.
 
2
   Copyright (C) 1998-2014 Free Software Foundation, Inc.
3
3
   This file is part of the GNU C Library.
4
4
   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
5
5
 
53
53
/* Definitions of arguments for argp functions.  */
54
54
static const struct argp_option options[] =
55
55
{
56
 
  { "output", 'o', N_("FILE"), 0, N_("Name output file") },
57
 
  { "string", 's', N_("STRING"), 0, N_("Title string used in output graphic") },
58
 
  { "time", 't', NULL, 0, N_("\
 
56
  { "output", 'o', N_ ("FILE"), 0, N_ ("Name output file") },
 
57
  { "string", 's', N_ ("STRING"), 0, N_ ("Title string used in output graphic") },
 
58
  { "time", 't', NULL, 0, N_ ("                                               \
59
59
Generate output linear to time (default is linear to number of function calls)\
60
60
") },
61
61
  { "total", 'T', NULL, 0,
62
 
    N_("Also draw graph for total memory consumption") },
63
 
  { "x-size", 'x', N_("VALUE"), 0,
64
 
    N_("Make output graphic VALUE pixels wide") },
65
 
  { "y-size", 'y', "VALUE", 0, N_("Make output graphic VALUE pixels high") },
 
62
    N_ ("Also draw graph for total memory consumption") },
 
63
  { "x-size", 'x', N_ ("VALUE"), 0,
 
64
    N_ ("Make output graphic VALUE pixels wide") },
 
65
  { "y-size", 'y', "VALUE", 0, N_ ("Make output graphic VALUE pixels high") },
66
66
  { NULL, 0, NULL, 0, NULL }
67
67
};
68
68
 
69
69
/* Short description of program.  */
70
 
static const char doc[] = N_("Generate graphic from memory profiling data");
 
70
static const char doc[] = N_ ("Generate graphic from memory profiling data");
71
71
 
72
72
/* Strings for arguments in help texts.  */
73
 
static const char args_doc[] = N_("DATAFILE [OUTFILE]");
 
73
static const char args_doc[] = N_ ("DATAFILE [OUTFILE]");
74
74
 
75
75
/* Prototype for option handler.  */
76
76
static error_t parse_opt (int key, char *arg, struct argp_state *state);
152
152
  if (remaining >= argc || remaining + 2 < argc)
153
153
    {
154
154
      argp_help (&argp, stdout, ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR,
155
 
                 program_invocation_short_name);
 
155
                 program_invocation_short_name);
156
156
      exit (1);
157
157
    }
158
158
 
197
197
  if (maxsize_heap == 0 && maxsize_stack == 0)
198
198
    {
199
199
      /* The program aborted before memusage was able to write the
200
 
         information about the maximum heap and stack use.  Repair
201
 
         the file now.  */
 
200
         information about the maximum heap and stack use.  Repair
 
201
         the file now.  */
202
202
      struct entry next;
203
203
 
204
204
      while (1)
205
 
        {
206
 
          if (read (fd, &next, sizeof (next)) == 0)
207
 
            break;
208
 
          if (next.heap > maxsize_heap)
209
 
            maxsize_heap = next.heap;
210
 
          if (next.stack > maxsize_stack)
211
 
            maxsize_stack = next.stack;
212
 
          if (maxsize_heap + maxsize_stack > maxsize_total)
213
 
            maxsize_total = maxsize_heap + maxsize_stack;
214
 
        }
 
205
        {
 
206
          if (read (fd, &next, sizeof (next)) == 0)
 
207
            break;
 
208
          if (next.heap > maxsize_heap)
 
209
            maxsize_heap = next.heap;
 
210
          if (next.stack > maxsize_stack)
 
211
            maxsize_stack = next.stack;
 
212
          if (maxsize_heap + maxsize_stack > maxsize_total)
 
213
            maxsize_total = maxsize_heap + maxsize_stack;
 
214
        }
215
215
 
216
216
      headent[0].stack = maxsize_total;
217
217
      headent[1].heap = maxsize_heap;
227
227
  if (also_total)
228
228
    {
229
229
      /* We use one scale and since we also draw the total amount of
230
 
         memory used we have to adapt the maximum.  */
 
230
         memory used we have to adapt the maximum.  */
231
231
      maxsize_heap = maxsize_total;
232
232
      maxsize_stack = maxsize_total;
233
233
    }
292
292
    }
293
293
 
294
294
  gdImageString (im_out, gdFontSmall, 38, ysize - 14, (unsigned char *) "0",
295
 
                 blue);
 
295
                 blue);
296
296
  snprintf (buf, sizeof (buf), heap_format, 0);
297
297
  gdImageString (im_out, gdFontSmall, maxsize_heap < 1024 ? 32 : 26,
298
 
                 ysize - 26, (unsigned char *) buf, red);
 
298
                 ysize - 26, (unsigned char *) buf, red);
299
299
  snprintf (buf, sizeof (buf), stack_format, 0);
300
300
  gdImageString (im_out, gdFontSmall, xsize - 37, ysize - 26,
301
 
                 (unsigned char *) buf, green);
 
301
                 (unsigned char *) buf, green);
302
302
 
303
303
  if (string != NULL)
304
304
    gdImageString (im_out, gdFontLarge, (xsize - strlen (string) * 8) / 2,
305
 
                   2, (unsigned char *) string, green);
 
305
                   2, (unsigned char *) string, green);
306
306
 
307
307
  gdImageStringUp (im_out, gdFontSmall, 1, ysize / 2 - 10,
308
 
                   (unsigned char *) "allocated", red);
 
308
                   (unsigned char *) "allocated", red);
309
309
  gdImageStringUp (im_out, gdFontSmall, 11, ysize / 2 - 10,
310
 
                   (unsigned char *) "memory", red);
 
310
                   (unsigned char *) "memory", red);
311
311
 
312
312
  gdImageStringUp (im_out, gdFontSmall, xsize - 39, ysize / 2 - 10,
313
 
                   (unsigned char *) "used", green);
 
313
                   (unsigned char *) "used", green);
314
314
  gdImageStringUp (im_out, gdFontSmall, xsize - 27, ysize / 2 - 10,
315
 
                   (unsigned char *) "stack", green);
 
315
                   (unsigned char *) "stack", green);
316
316
 
317
317
  snprintf (buf, sizeof (buf), heap_format, maxsize_heap / heap_scale);
318
318
  gdImageString (im_out, gdFontSmall, 39 - strlen (buf) * 6, 14,
319
 
                 (unsigned char *) buf, red);
 
319
                 (unsigned char *) buf, red);
320
320
  snprintf (buf, sizeof (buf), stack_format, maxsize_stack / stack_scale);
321
321
  gdImageString (im_out, gdFontSmall, xsize - 37, 14,
322
 
                 (unsigned char *) buf, green);
 
322
                 (unsigned char *) buf, green);
323
323
 
324
324
  for (line = 1; line <= 3; ++line)
325
325
    {
326
326
      if (maxsize_heap > 0)
327
 
        {
328
 
          cnt = (((ysize - 40) * (maxsize_heap / 4 * line / heap_scale))
329
 
                 / (maxsize_heap / heap_scale));
330
 
          gdImageDashedLine (im_out, 40, ysize - 20 - cnt, xsize - 40,
331
 
                             ysize - 20 - cnt, red);
332
 
          snprintf (buf, sizeof (buf), heap_format,
333
 
                    maxsize_heap / 4 * line / heap_scale);
334
 
          gdImageString (im_out, gdFontSmall, 39 - strlen (buf) * 6,
335
 
                         ysize - 26 - cnt, (unsigned char *) buf, red);
336
 
        }
 
327
        {
 
328
          cnt = (((ysize - 40) * (maxsize_heap / 4 * line / heap_scale))
 
329
                 / (maxsize_heap / heap_scale));
 
330
          gdImageDashedLine (im_out, 40, ysize - 20 - cnt, xsize - 40,
 
331
                             ysize - 20 - cnt, red);
 
332
          snprintf (buf, sizeof (buf), heap_format,
 
333
                    maxsize_heap / 4 * line / heap_scale);
 
334
          gdImageString (im_out, gdFontSmall, 39 - strlen (buf) * 6,
 
335
                         ysize - 26 - cnt, (unsigned char *) buf, red);
 
336
        }
337
337
      else
338
 
        cnt = 0;
 
338
        cnt = 0;
339
339
 
340
340
      if (maxsize_stack > 0)
341
 
        cnt2 = (((ysize - 40) * (maxsize_stack / 4 * line / stack_scale))
342
 
                / (maxsize_stack / stack_scale));
 
341
        cnt2 = (((ysize - 40) * (maxsize_stack / 4 * line / stack_scale))
 
342
                / (maxsize_stack / stack_scale));
343
343
      else
344
 
        cnt2 = 0;
 
344
        cnt2 = 0;
345
345
 
346
346
      if (cnt != cnt2)
347
 
        gdImageDashedLine (im_out, 40, ysize - 20 - cnt2, xsize - 40,
348
 
                           ysize - 20 - cnt2, green);
 
347
        gdImageDashedLine (im_out, 40, ysize - 20 - cnt2, xsize - 40,
 
348
                           ysize - 20 - cnt2, green);
349
349
      snprintf (buf, sizeof (buf), stack_format, maxsize_stack / 4 * line /
350
 
                stack_scale);
 
350
                stack_scale);
351
351
      gdImageString (im_out, gdFontSmall, xsize - 37, ysize - 26 - cnt2,
352
 
                     (unsigned char *) buf, green);
 
352
                     (unsigned char *) buf, green);
353
353
    }
354
354
 
355
355
  snprintf (buf, sizeof (buf), "%llu", (unsigned long long) total);
356
356
  gdImageString (im_out, gdFontSmall, xsize - 50, ysize - 14,
357
 
                 (unsigned char *) buf, blue);
 
357
                 (unsigned char *) buf, blue);
358
358
 
359
359
  if (!time_based)
360
360
    {
361
361
      uint64_t previously = start_time;
362
362
 
363
363
      gdImageString (im_out, gdFontSmall, 40 + (xsize - 32 * 6 - 80) / 2,
364
 
                     ysize - 12,
365
 
                     (unsigned char *) "# memory handling function calls",
366
 
                     blue);
 
364
                     ysize - 12,
 
365
                     (unsigned char *) "# memory handling function calls",
 
366
                     blue);
367
367
 
368
368
 
369
369
      last_stack = last_heap = last_total = ysize - 20;
370
370
      for (cnt = 1; cnt <= total; ++cnt)
371
 
        {
372
 
          struct entry entry;
373
 
          size_t new[2];
374
 
          uint64_t now;
375
 
 
376
 
          read (fd, &entry, sizeof (entry));
377
 
 
378
 
          now = ((uint64_t) entry.time_high) << 32 | entry.time_low;
379
 
 
380
 
          if ((((previously - start_time) * 100) / total_time) % 10 < 5)
381
 
            gdImageFilledRectangle (im_out,
382
 
                                    40 + ((cnt - 1) * (xsize - 80)) / total,
383
 
                                    ysize - 19,
384
 
                                    39 + (cnt * (xsize - 80)) / total,
385
 
                                    ysize - 14, yellow);
386
 
          previously = now;
387
 
 
388
 
          if (also_total && maxsize_heap > 0)
389
 
            {
390
 
              size_t new3;
391
 
 
392
 
              new3 = (ysize - 20) - ((((unsigned long long int) (ysize - 40))
393
 
                                      * (entry.heap + entry.stack))
394
 
                                     / maxsize_heap);
395
 
              gdImageLine (im_out, 40 + ((xsize - 80) * (cnt - 1)) / total,
396
 
                           last_total,
397
 
                           40 + ((xsize - 80) * cnt) / total, new3,
398
 
                           black);
399
 
              last_total = new3;
400
 
            }
401
 
 
402
 
          if (maxsize_heap > 0)
403
 
            {
404
 
              new[0] = ((ysize - 20)
405
 
                        - ((((unsigned long long int) (ysize - 40))
406
 
                            * entry.heap) / maxsize_heap));
407
 
              gdImageLine (im_out, 40 + ((xsize - 80) * (cnt - 1)) / total,
408
 
                           last_heap, 40 + ((xsize - 80) * cnt) / total,
409
 
                           new[0], red);
410
 
              last_heap = new[0];
411
 
            }
412
 
 
413
 
          if (maxsize_stack > 0)
414
 
            {
415
 
              new[1] = ((ysize - 20)
416
 
                        - ((((unsigned long long int) (ysize - 40))
417
 
                            * entry.stack) / maxsize_stack));
418
 
              gdImageLine (im_out, 40 + ((xsize - 80) * (cnt - 1)) / total,
419
 
                           last_stack, 40 + ((xsize - 80) * cnt) / total,
420
 
                           new[1], green);
421
 
              last_stack = new[1];
422
 
            }
423
 
        }
 
371
        {
 
372
          struct entry entry;
 
373
          size_t new[2];
 
374
          uint64_t now;
 
375
 
 
376
          read (fd, &entry, sizeof (entry));
 
377
 
 
378
          now = ((uint64_t) entry.time_high) << 32 | entry.time_low;
 
379
 
 
380
          if ((((previously - start_time) * 100) / total_time) % 10 < 5)
 
381
            gdImageFilledRectangle (im_out,
 
382
                                    40 + ((cnt - 1) * (xsize - 80)) / total,
 
383
                                    ysize - 19,
 
384
                                    39 + (cnt * (xsize - 80)) / total,
 
385
                                    ysize - 14, yellow);
 
386
          previously = now;
 
387
 
 
388
          if (also_total && maxsize_heap > 0)
 
389
            {
 
390
              size_t new3;
 
391
 
 
392
              new3 = (ysize - 20) - ((((unsigned long long int) (ysize - 40))
 
393
                                      * (entry.heap + entry.stack))
 
394
                                     / maxsize_heap);
 
395
              gdImageLine (im_out, 40 + ((xsize - 80) * (cnt - 1)) / total,
 
396
                           last_total,
 
397
                           40 + ((xsize - 80) * cnt) / total, new3,
 
398
                           black);
 
399
              last_total = new3;
 
400
            }
 
401
 
 
402
          if (maxsize_heap > 0)
 
403
            {
 
404
              new[0] = ((ysize - 20)
 
405
                        - ((((unsigned long long int) (ysize - 40))
 
406
                            * entry.heap) / maxsize_heap));
 
407
              gdImageLine (im_out, 40 + ((xsize - 80) * (cnt - 1)) / total,
 
408
                           last_heap, 40 + ((xsize - 80) * cnt) / total,
 
409
                           new[0], red);
 
410
              last_heap = new[0];
 
411
            }
 
412
 
 
413
          if (maxsize_stack > 0)
 
414
            {
 
415
              new[1] = ((ysize - 20)
 
416
                        - ((((unsigned long long int) (ysize - 40))
 
417
                            * entry.stack) / maxsize_stack));
 
418
              gdImageLine (im_out, 40 + ((xsize - 80) * (cnt - 1)) / total,
 
419
                           last_stack, 40 + ((xsize - 80) * cnt) / total,
 
420
                           new[1], green);
 
421
              last_stack = new[1];
 
422
            }
 
423
        }
424
424
 
425
425
      cnt = 0;
426
426
      while (cnt < total)
427
 
        {
428
 
          gdImageLine (im_out, 40 + ((xsize - 80) * cnt) / total, ysize - 20,
429
 
                       40 + ((xsize - 80) * cnt) / total, ysize - 15, blue);
430
 
          cnt += MAX (1, total / 20);
431
 
        }
 
427
        {
 
428
          gdImageLine (im_out, 40 + ((xsize - 80) * cnt) / total, ysize - 20,
 
429
                       40 + ((xsize - 80) * cnt) / total, ysize - 15, blue);
 
430
          cnt += MAX (1, total / 20);
 
431
        }
432
432
      gdImageLine (im_out, xsize - 40, ysize - 20, xsize - 40, ysize - 15,
433
 
                   blue);
 
433
                   blue);
434
434
    }
435
435
  else
436
436
    {
438
438
      size_t last_xpos = 40;
439
439
 
440
440
      gdImageString (im_out, gdFontSmall, 40 + (xsize - 39 * 6 - 80) / 2,
441
 
                     ysize - 12,
442
 
                     (unsigned char *) "\
 
441
                     ysize - 12,
 
442
                     (unsigned char *) "                                      \
443
443
# memory handling function calls / time", blue);
444
444
 
445
445
      for (cnt = 0; cnt < 20; cnt += 2)
446
 
        gdImageFilledRectangle (im_out,
447
 
                                40 + (cnt * (xsize - 80)) / 20, ysize - 19,
448
 
                                39 + ((cnt + 1) * (xsize - 80)) / 20,
449
 
                                ysize - 14, yellow);
 
446
        gdImageFilledRectangle (im_out,
 
447
                                40 + (cnt * (xsize - 80)) / 20, ysize - 19,
 
448
                                39 + ((cnt + 1) * (xsize - 80)) / 20,
 
449
                                ysize - 14, yellow);
450
450
 
451
451
      last_stack = last_heap = last_total = ysize - 20;
452
452
      for (cnt = 1; cnt <= total; ++cnt)
453
 
        {
454
 
          struct entry entry;
455
 
          size_t new[2];
456
 
          size_t xpos;
457
 
          uint64_t now;
458
 
 
459
 
          read (fd, &entry, sizeof (entry));
460
 
 
461
 
          now = ((uint64_t) entry.time_high) << 32 | entry.time_low;
462
 
          xpos = 40 + ((xsize - 80) * (now - start_time)) / total_time;
463
 
 
464
 
          if (cnt == next_tick)
465
 
            {
466
 
              gdImageLine (im_out, xpos, ysize - 20, xpos, ysize - 15, blue);
467
 
              next_tick += MAX (1, total / 20);
468
 
            }
469
 
 
470
 
          if (also_total && maxsize_heap > 0)
471
 
            {
472
 
              size_t new3;
473
 
 
474
 
              new3 = (ysize - 20) - ((((unsigned long long int) (ysize - 40))
475
 
                                      * (entry.heap + entry.stack))
476
 
                                     / maxsize_heap);
477
 
              gdImageLine (im_out, last_xpos, last_total, xpos, new3, black);
478
 
              last_total = new3;
479
 
            }
480
 
 
481
 
          if (maxsize_heap > 0)
482
 
            {
483
 
              new[0] = ((ysize - 20)
484
 
                        - ((((unsigned long long int) (ysize - 40))
485
 
                            * entry.heap) / maxsize_heap));
486
 
              gdImageLine (im_out, last_xpos, last_heap, xpos, new[0], red);
487
 
              last_heap = new[0];
488
 
            }
489
 
 
490
 
          if (maxsize_stack > 0)
491
 
            {
492
 
              new[1] = ((ysize - 20)
493
 
                        - ((((unsigned long long int) (ysize - 40))
494
 
                            * entry.stack) / maxsize_stack));
495
 
              gdImageLine (im_out, last_xpos, last_stack, xpos, new[1],
496
 
                           green);
497
 
              last_stack = new[1];
498
 
            }
499
 
 
500
 
          last_xpos = xpos;
501
 
        }
 
453
        {
 
454
          struct entry entry;
 
455
          size_t new[2];
 
456
          size_t xpos;
 
457
          uint64_t now;
 
458
 
 
459
          read (fd, &entry, sizeof (entry));
 
460
 
 
461
          now = ((uint64_t) entry.time_high) << 32 | entry.time_low;
 
462
          xpos = 40 + ((xsize - 80) * (now - start_time)) / total_time;
 
463
 
 
464
          if (cnt == next_tick)
 
465
            {
 
466
              gdImageLine (im_out, xpos, ysize - 20, xpos, ysize - 15, blue);
 
467
              next_tick += MAX (1, total / 20);
 
468
            }
 
469
 
 
470
          if (also_total && maxsize_heap > 0)
 
471
            {
 
472
              size_t new3;
 
473
 
 
474
              new3 = (ysize - 20) - ((((unsigned long long int) (ysize - 40))
 
475
                                      * (entry.heap + entry.stack))
 
476
                                     / maxsize_heap);
 
477
              gdImageLine (im_out, last_xpos, last_total, xpos, new3, black);
 
478
              last_total = new3;
 
479
            }
 
480
 
 
481
          if (maxsize_heap > 0)
 
482
            {
 
483
              new[0] = ((ysize - 20)
 
484
                        - ((((unsigned long long int) (ysize - 40))
 
485
                            * entry.heap) / maxsize_heap));
 
486
              gdImageLine (im_out, last_xpos, last_heap, xpos, new[0], red);
 
487
              last_heap = new[0];
 
488
            }
 
489
 
 
490
          if (maxsize_stack > 0)
 
491
            {
 
492
              new[1] = ((ysize - 20)
 
493
                        - ((((unsigned long long int) (ysize - 40))
 
494
                            * entry.stack) / maxsize_stack));
 
495
              gdImageLine (im_out, last_xpos, last_stack, xpos, new[1],
 
496
                           green);
 
497
              last_stack = new[1];
 
498
            }
 
499
 
 
500
          last_xpos = xpos;
 
501
        }
502
502
    }
503
503
 
504
504
  /* Write out the result.  */
537
537
    case 'x':
538
538
      xsize = atoi (arg);
539
539
      if (xsize == 0)
540
 
        xsize = XSIZE;
 
540
        xsize = XSIZE;
541
541
      break;
542
542
    case 'y':
543
543
      ysize = atoi (arg);
544
544
      if (ysize == 0)
545
 
        ysize = XSIZE;
 
545
        ysize = XSIZE;
546
546
      break;
547
547
    default:
548
548
      return ARGP_ERR_UNKNOWN;
563
563
      if (asprintf (&tp, gettext ("\
564
564
For bug reporting instructions, please see:\n\
565
565
%s.\n"), REPORT_BUGS_TO) < 0)
566
 
        return NULL;
 
566
        return NULL;
 
567
 
567
568
      return tp;
 
569
 
568
570
    default:
569
571
      break;
570
572
    }
580
582
Copyright (C) %s Free Software Foundation, Inc.\n\
581
583
This is free software; see the source for copying conditions.  There is NO\n\
582
584
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
583
 
"), "2013");
 
585
"), "2014");
584
586
  fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
585
587
}