Back to index

cell-binutils  2.17cvs20070401
Functions | Variables
hist.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void hist_read_rec (FILE *, const char *)
void hist_write_hist (FILE *, const char *)
void hist_assign_samples (void)
void hist_print (void)

Variables

bfd_vma s_lowpc
bfd_vma s_highpc
bfd_vma lowpc
bfd_vma highpc
unsigned int hist_num_bins
inthist_sample
double hist_scale

Function Documentation

void hist_assign_samples ( void  )

Definition at line 262 of file hist.c.

{
  bfd_vma bin_low_pc, bin_high_pc;
  bfd_vma sym_low_pc, sym_high_pc;
  bfd_vma overlap, addr;
  unsigned int bin_count;
  unsigned int i, j;
  double time, credit;

  /* Read samples and assign to symbols.  */
  hist_scale = highpc - lowpc;
  hist_scale /= hist_num_bins;
  scale_and_align_entries ();

  /* Iterate over all sample bins.  */
  for (i = 0, j = 1; i < hist_num_bins; ++i)
    {
      bin_count = hist_sample[i];
      if (! bin_count)
       continue;

      bin_low_pc = lowpc + (bfd_vma) (hist_scale * i);
      bin_high_pc = lowpc + (bfd_vma) (hist_scale * (i + 1));
      time = bin_count;

      DBG (SAMPLEDEBUG,
          printf (
      "[assign_samples] bin_low_pc=0x%lx, bin_high_pc=0x%lx, bin_count=%u\n",
                  (unsigned long) (sizeof (UNIT) * bin_low_pc),
                  (unsigned long) (sizeof (UNIT) * bin_high_pc),
                  bin_count));
      total_time += time;

      /* Credit all symbols that are covered by bin I.  */
      for (j = j - 1; j < symtab.len; ++j)
       {
         sym_low_pc = symtab.base[j].hist.scaled_addr;
         sym_high_pc = symtab.base[j + 1].hist.scaled_addr;

         /* If high end of bin is below entry address,
            go for next bin.  */
         if (bin_high_pc < sym_low_pc)
           break;

         /* If low end of bin is above high end of symbol,
            go for next symbol.  */
         if (bin_low_pc >= sym_high_pc)
           continue;

         overlap =
           MIN (bin_high_pc, sym_high_pc) - MAX (bin_low_pc, sym_low_pc);
         if (overlap > 0)
           {
             DBG (SAMPLEDEBUG,
                 printf (
              "[assign_samples] [0x%lx,0x%lx) %s gets %f ticks %ld overlap\n",
                        (unsigned long) symtab.base[j].addr,
                        (unsigned long) (sizeof (UNIT) * sym_high_pc),
                        symtab.base[j].name, overlap * time / hist_scale,
                        (long) overlap));

             addr = symtab.base[j].addr;
             credit = overlap * time / hist_scale;

             /* Credit symbol if it appears in INCL_FLAT or that
               table is empty and it does not appear it in
               EXCL_FLAT.  */
             if (sym_lookup (&syms[INCL_FLAT], addr)
                || (syms[INCL_FLAT].len == 0
                    && !sym_lookup (&syms[EXCL_FLAT], addr)))
              {
                symtab.base[j].hist.time += credit;
              }
             else
              {
                total_time -= credit;
              }
           }
       }
    }

  DBG (SAMPLEDEBUG, printf ("[assign_samples] total_time %f\n",
                         total_time));
}

Here is the call graph for this function:

Here is the caller graph for this function:

void hist_print ( void  )

Definition at line 454 of file hist.c.

{
  Sym **time_sorted_syms, *top_dog, *sym;
  unsigned int index;
  unsigned log_scale;
  double top_time, time;
  bfd_vma addr;

  if (first_output)
    first_output = FALSE;
  else
    printf ("\f\n");

  accum_time = 0.0;

  if (bsd_style_output)
    {
      if (print_descriptions)
       {
         printf (_("\n\n\nflat profile:\n"));
         flat_blurb (stdout);
       }
    }
  else
    {
      printf (_("Flat profile:\n"));
    }

  /* Sort the symbol table by time (call-count and name as secondary
     and tertiary keys).  */
  time_sorted_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *));

  for (index = 0; index < symtab.len; ++index)
    time_sorted_syms[index] = &symtab.base[index];

  qsort (time_sorted_syms, symtab.len, sizeof (Sym *), cmp_time);

  if (bsd_style_output)
    {
      log_scale = 5;        /* Milli-seconds is BSD-default.  */
    }
  else
    {
      /* Search for symbol with highest per-call
        execution time and scale accordingly.  */
      log_scale = 0;
      top_dog = 0;
      top_time = 0.0;

      for (index = 0; index < symtab.len; ++index)
       {
         sym = time_sorted_syms[index];

         if (sym->ncalls != 0)
           {
             time = (sym->hist.time + sym->cg.child_time) / sym->ncalls;

             if (time > top_time)
              {
                top_dog = sym;
                top_time = time;
              }
           }
       }

      if (top_dog && top_dog->ncalls != 0 && top_time > 0.0)
       {
         top_time /= hz;

         for (log_scale = 0; log_scale < ARRAY_SIZE (SItab); log_scale ++)
           {
             double scaled_value = SItab[log_scale].scale * top_time;

             if (scaled_value >= 1.0 && scaled_value < 1000.0) 
              break;
           }
       }
    }

  /* For now, the dimension is always seconds.  In the future, we
     may also want to support other (pseudo-)dimensions (such as
     I-cache misses etc.).  */
  print_header (SItab[log_scale].prefix);

  for (index = 0; index < symtab.len; ++index)
    {
      addr = time_sorted_syms[index]->addr;

      /* Print symbol if its in INCL_FLAT table or that table
       is empty and the symbol is not in EXCL_FLAT.  */
      if (sym_lookup (&syms[INCL_FLAT], addr)
         || (syms[INCL_FLAT].len == 0
             && !sym_lookup (&syms[EXCL_FLAT], addr)))
       print_line (time_sorted_syms[index], SItab[log_scale].scale);
    }

  free (time_sorted_syms);

  if (print_descriptions && !bsd_style_output)
    flat_blurb (stdout);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void hist_read_rec ( FILE *  ,
const char *   
)

Definition at line 84 of file hist.c.

{
  bfd_vma n_lowpc, n_highpc;
  unsigned int i, ncnt, profrate;
  UNIT count;

  if (gmon_io_read_vma (ifp, &n_lowpc)
      || gmon_io_read_vma (ifp, &n_highpc)
      || gmon_io_read_32 (ifp, &ncnt)
      || gmon_io_read_32 (ifp, &profrate)
      || gmon_io_read (ifp, hist_dimension, 15)
      || gmon_io_read (ifp, &hist_dimension_abbrev, 1))
    {
      fprintf (stderr, _("%s: %s: unexpected end of file\n"),
              whoami, filename);

      done (1);
    }

  if (!s_highpc)
    {
      /* This is the first histogram record.  */
      s_lowpc = n_lowpc;
      s_highpc = n_highpc;
      lowpc = (bfd_vma) n_lowpc / sizeof (UNIT);
      highpc = (bfd_vma) n_highpc / sizeof (UNIT);
      hist_num_bins = ncnt;
      hz = profrate;
    }

  DBG (SAMPLEDEBUG,
       printf ("[hist_read_rec] n_lowpc 0x%lx n_highpc 0x%lx ncnt %u\n",
              (unsigned long) n_lowpc, (unsigned long) n_highpc, ncnt);
       printf ("[hist_read_rec] s_lowpc 0x%lx s_highpc 0x%lx nsamples %u\n",
              (unsigned long) s_lowpc, (unsigned long) s_highpc,
              hist_num_bins);
       printf ("[hist_read_rec]   lowpc 0x%lx   highpc 0x%lx\n",
              (unsigned long) lowpc, (unsigned long) highpc));

  if (n_lowpc != s_lowpc || n_highpc != s_highpc
      || ncnt != hist_num_bins || hz != (int) profrate)
    {
      fprintf (stderr, _("%s: `%s' is incompatible with first gmon file\n"),
              whoami, filename);
      done (1);
    }

  if (!hist_sample)
    {
      hist_sample = (int *) xmalloc (hist_num_bins * sizeof (hist_sample[0]));
      memset (hist_sample, 0, hist_num_bins * sizeof (hist_sample[0]));
    }

  for (i = 0; i < hist_num_bins; ++i)
    {
      if (fread (&count[0], sizeof (count), 1, ifp) != 1)
       {
         fprintf (stderr,
                _("%s: %s: unexpected EOF after reading %u of %u samples\n"),
                 whoami, filename, i, hist_num_bins);
         done (1);
       }
      hist_sample[i] += bfd_get_16 (core_bfd, (bfd_byte *) & count[0]);
      DBG (SAMPLEDEBUG,
          printf ("[hist_read_rec] 0x%lx: %u\n",
                 (unsigned long) (n_lowpc + i * (n_highpc - n_lowpc) / ncnt),
                 hist_sample[i]));
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void hist_write_hist ( FILE *  ,
const char *   
)

Definition at line 159 of file hist.c.

{
  UNIT count;
  unsigned int i;

  /* Write header.  */

  if (gmon_io_write_8 (ofp, GMON_TAG_TIME_HIST)
      || gmon_io_write_vma (ofp, s_lowpc)
      || gmon_io_write_vma (ofp, s_highpc)
      || gmon_io_write_32 (ofp, hist_num_bins)
      || gmon_io_write_32 (ofp, hz)
      || gmon_io_write (ofp, hist_dimension, 15)
      || gmon_io_write (ofp, &hist_dimension_abbrev, 1))
    {
      perror (filename);
      done (1);
    }

  for (i = 0; i < hist_num_bins; ++i)
    {
      bfd_put_16 (core_bfd, (bfd_vma) hist_sample[i], (bfd_byte *) &count[0]);

      if (fwrite (&count[0], sizeof (count), 1, ofp) != 1)
       {
         perror (filename);
         done (1);
       }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 47 of file hist.c.

Definition at line 48 of file hist.c.

Definition at line 49 of file hist.c.

Definition at line 50 of file hist.c.

Definition at line 47 of file hist.c.

Definition at line 46 of file hist.c.

Definition at line 45 of file hist.c.