home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / gdb-4.16-base.tgz / gdb-4.16-base.tar / fsf / gdb / sim / ppc / mon.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-19  |  8.9 KB  |  371 lines

  1. /*  This file is part of the program psim.
  2.  
  3.     Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
  4.  
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation; either version 2 of the License, or
  8.     (at your option) any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18.  
  19.     */
  20.  
  21.  
  22. #ifndef _MON_C_
  23. #define _MON_C_
  24.  
  25. #include "basics.h"
  26. #include "cpu.h"
  27. #include "mon.h"
  28. #include <stdio.h>
  29.  
  30. #ifdef HAVE_STRING_H
  31. #include <string.h>
  32. #else
  33. #ifdef HAVE_STRINGS_H
  34. #include <strings.h>
  35. #endif
  36. #endif
  37.  
  38. #ifdef HAVE_UNISTD_H
  39. #include <unistd.h>
  40. #endif
  41.  
  42. #ifdef HAVE_STDLIB_H
  43. #include <stdlib.h>
  44. #endif
  45.  
  46. #ifdef HAVE_SYS_TYPES_H
  47. #include <sys/types.h>
  48. #endif
  49.  
  50. #ifdef HAVE_TIME_H
  51. #include <time.h>
  52. #endif
  53.  
  54. #ifdef HAVE_SYS_TIMES_H
  55. #include <sys/times.h>
  56. #endif
  57.  
  58. #ifdef HAVE_SYS_TIME_H
  59. #include <sys/time.h>
  60. #endif
  61.  
  62. #ifdef HAVE_SYS_RESOURCE_H
  63. #include <sys/resource.h>
  64. int getrusage();
  65. #endif
  66.  
  67. struct _cpu_mon {
  68.   count_type issue_count[nr_itable_entries];
  69.   count_type read_count;
  70.   count_type write_count;
  71.   count_type unaligned_read_count;
  72.   count_type unaligned_write_count;
  73.   count_type event_count[nr_mon_events];
  74. };
  75.  
  76. struct _mon {
  77.   int nr_cpus;
  78.   cpu_mon cpu_monitor[MAX_NR_PROCESSORS];
  79. };
  80.  
  81.  
  82. INLINE_MON\
  83. (mon *)
  84. mon_create(void)
  85. {
  86.   mon *monitor = ZALLOC(mon);
  87.   return monitor;
  88. }
  89.  
  90.  
  91. INLINE_MON\
  92. (cpu_mon *)
  93. mon_cpu(mon *monitor,
  94.     int cpu_nr)
  95. {
  96.   if (cpu_nr < 0 || cpu_nr >= MAX_NR_PROCESSORS)
  97.     error("mon_cpu() - invalid cpu number\n");
  98.   return &monitor->cpu_monitor[cpu_nr];
  99. }
  100.  
  101.  
  102. INLINE_MON\
  103. (void)
  104. mon_init(mon *monitor,
  105.      int nr_cpus)
  106. {
  107.   memset(monitor, 0, sizeof(*monitor));
  108.   monitor->nr_cpus = nr_cpus;
  109. }
  110.  
  111.  
  112. INLINE_MON\
  113. (void)
  114. mon_issue(itable_index index,
  115.       cpu *processor, 
  116.       unsigned_word cia)
  117. {
  118.   cpu_mon *monitor = cpu_monitor(processor);
  119.   ASSERT(index <= nr_itable_entries);
  120.   monitor->issue_count[index] += 1;
  121. }
  122.  
  123.  
  124. INLINE_MON\
  125. (void)
  126. mon_read(unsigned_word ea,
  127.      unsigned_word ra,
  128.      unsigned nr_bytes,
  129.      cpu *processor,
  130.      unsigned_word cia)
  131. {
  132.   cpu_mon *monitor = cpu_monitor(processor);
  133.   monitor->read_count += 1;
  134.   if ((nr_bytes - 1) & ea)
  135.     monitor->unaligned_read_count += 1;
  136. }
  137.  
  138.  
  139. INLINE_MON\
  140. (void)
  141. mon_write(unsigned_word ea,
  142.       unsigned_word ra,
  143.       unsigned nr_bytes,
  144.       cpu *processor,
  145.       unsigned_word cia)
  146. {
  147.   cpu_mon *monitor = cpu_monitor(processor);
  148.   monitor->write_count += 1;
  149.   if ((nr_bytes - 1) & ea)
  150.     monitor->unaligned_write_count += 1;
  151. }
  152.  
  153. INLINE_MON\
  154. (void)
  155. mon_event(mon_events event,
  156.       cpu *processor,
  157.       unsigned_word cia)
  158. {
  159.   cpu_mon *monitor = cpu_monitor(processor);
  160.   ASSERT(event >= 0 && event < nr_mon_events);
  161.   monitor->event_count[event] += 1;
  162. }
  163.  
  164. STATIC_INLINE_MON\
  165. (count_type)
  166. mon_get_number_of_insns(cpu_mon *monitor)
  167. {
  168.   itable_index index;
  169.   count_type total_insns = 0;
  170.   for (index = 0; index < nr_itable_entries; index++)
  171.     total_insns += monitor->issue_count[index];
  172.   return total_insns;
  173. }
  174.  
  175. static int
  176. mon_sort_instruction_names(const void *ptr_a, const void *ptr_b)
  177. {
  178.   itable_index a = *(const itable_index *)ptr_a;
  179.   itable_index b = *(const itable_index *)ptr_b;
  180.  
  181.   return strcmp (itable[a].name, itable[b].name);
  182. }
  183.  
  184. STATIC_INLINE_MON\
  185. (char *)
  186. mon_add_commas(char *buf,
  187.            int sizeof_buf,
  188.            count_type value)
  189. {
  190.   int comma = 3;
  191.   char *endbuf = buf + sizeof_buf - 1;
  192.  
  193.   *--endbuf = '\0';
  194.   do {
  195.     if (comma-- == 0)
  196.       {
  197.     *--endbuf = ',';
  198.     comma = 2;
  199.       }
  200.  
  201.     *--endbuf = (value % 10) + '0';
  202.   } while ((value /= 10) != 0);
  203.  
  204.   ASSERT(endbuf >= buf);
  205.   return endbuf;
  206. }
  207.  
  208.  
  209. INLINE_MON\
  210. (void)
  211. mon_print_info(psim *system,
  212.            mon *monitor,
  213.            int verbose)
  214. {
  215.   char buffer[20];
  216.   int cpu_nr;
  217.   int len_cpu;
  218.   int len_num = 0;
  219.   int len;
  220.   long total_insns = 0;
  221.   long cpu_insns_second = 0;
  222.   double cpu_time = 0.0;
  223.  
  224.   for (cpu_nr = 0; cpu_nr < monitor->nr_cpus; cpu_nr++) {
  225.     count_type num_insns = mon_get_number_of_insns(&monitor->cpu_monitor[cpu_nr]);
  226.  
  227.     total_insns += num_insns;
  228.     len = strlen (mon_add_commas(buffer, sizeof(buffer), num_insns));
  229.     if (len_num < len)
  230.       len_num = len;
  231.   }
  232.  
  233.   sprintf (buffer, "%d", (int)monitor->nr_cpus + 1);
  234.   len_cpu = strlen (buffer);
  235.  
  236. #ifdef HAVE_GETRUSAGE
  237.   {
  238.     struct rusage mytime;
  239.     if (getrusage (RUSAGE_SELF, &mytime) == 0
  240.     && (mytime.ru_utime.tv_sec > 0 || mytime.ru_utime.tv_usec > 0)) {
  241.       
  242.       cpu_time = (double)mytime.ru_utime.tv_sec + (((double)mytime.ru_utime.tv_usec) / 1000000.0);
  243.     }
  244.   }
  245.   if (cpu_time > 0 && total_insns > 0)
  246.     cpu_insns_second = (long)(((double)total_insns / cpu_time) + 0.5);
  247. #endif
  248.  
  249.   for (cpu_nr = 0; cpu_nr < monitor->nr_cpus; cpu_nr++) {
  250.  
  251.     if (verbose > 1) {
  252.       itable_index sort_insns[nr_itable_entries];
  253.       int nr_sort_insns = 0;
  254.       itable_index index;
  255.       int index2;
  256.  
  257.       if (cpu_nr)
  258.     printf_filtered ("\n");
  259.  
  260.       for (index = 0; index < nr_itable_entries; index++) {
  261.     if (monitor->cpu_monitor[cpu_nr].issue_count[index]) {
  262.       sort_insns[nr_sort_insns++] = index;
  263.     }
  264.       }
  265.  
  266.       qsort((void *)sort_insns, nr_sort_insns, sizeof(sort_insns[0]), mon_sort_instruction_names);
  267.  
  268.       for (index2 = 0; index2 < nr_sort_insns; index2++) {
  269.     index = sort_insns[index2];
  270.     printf_filtered("CPU #%*d executed %*s %s instruction%s.\n",
  271.             len_cpu, cpu_nr+1,
  272.             len_num, mon_add_commas(buffer,
  273.                         sizeof(buffer),
  274.                         monitor->cpu_monitor[cpu_nr].issue_count[index]),
  275.               itable[index].name,
  276.               (monitor->cpu_monitor[cpu_nr].issue_count[index] == 1) ? "" : "s");
  277.       }
  278.  
  279.       printf_filtered ("\n");
  280.     }
  281.  
  282.     if (CURRENT_MODEL_ISSUE > 0)
  283.       {
  284.     model_data *model_ptr = cpu_model(psim_cpu(system, cpu_nr));
  285.     model_print *ptr = model_mon_info(model_ptr);
  286.     model_print *orig_ptr = ptr;
  287.  
  288.     while (ptr) {
  289.       if (ptr->count)
  290.         printf_filtered("CPU #%*d executed %*s %s%s.\n",
  291.                 len_cpu, cpu_nr+1,
  292.                 len_num, mon_add_commas(buffer,
  293.                             sizeof(buffer),
  294.                             ptr->count),
  295.                 ptr->name,
  296.                 ((ptr->count == 1)
  297.                  ? ptr->suffix_singular
  298.                  : ptr->suffix_plural));
  299.  
  300.       ptr = ptr->next;
  301.     }
  302.  
  303.     model_mon_info_free(model_ptr, orig_ptr);
  304.       }
  305.  
  306.     if (monitor->cpu_monitor[cpu_nr].read_count)
  307.       printf_filtered ("CPU #%*d executed %*s data read%s.\n",
  308.                len_cpu, cpu_nr+1,
  309.                len_num, mon_add_commas(buffer,
  310.                            sizeof(buffer),
  311.                            monitor->cpu_monitor[cpu_nr].read_count),
  312.                (monitor->cpu_monitor[cpu_nr].read_count == 1) ? "" : "s");
  313.  
  314.     if (monitor->cpu_monitor[cpu_nr].write_count)
  315.       printf_filtered ("CPU #%*d executed %*s data write%s.\n",
  316.                len_cpu, cpu_nr+1,
  317.                len_num, mon_add_commas(buffer,
  318.                            sizeof(buffer),
  319.                            monitor->cpu_monitor[cpu_nr].write_count),
  320.                (monitor->cpu_monitor[cpu_nr].write_count == 1) ? "" : "s");
  321.  
  322.     if (monitor->cpu_monitor[cpu_nr].unaligned_read_count)
  323.       printf_filtered ("CPU #%*d executed %*s unaligned data read%s.\n",
  324.                len_cpu, cpu_nr+1,
  325.                len_num, mon_add_commas(buffer,
  326.                            sizeof(buffer),
  327.                            monitor->cpu_monitor[cpu_nr].read_count),
  328.                (monitor->cpu_monitor[cpu_nr].read_count == 1) ? "" : "s");
  329.  
  330.     if (monitor->cpu_monitor[cpu_nr].unaligned_write_count)
  331.       printf_filtered ("CPU #%*d executed %*s unaligned data write%s.\n",
  332.                len_cpu, cpu_nr+1,
  333.                len_num, mon_add_commas(buffer,
  334.                            sizeof(buffer),
  335.                            monitor->cpu_monitor[cpu_nr].write_count),
  336.                (monitor->cpu_monitor[cpu_nr].write_count == 1) ? "" : "s");
  337.     
  338.     if (monitor->cpu_monitor[cpu_nr].event_count[mon_event_icache_miss])
  339.       printf_filtered ("CPU #%*d executed %*s icache miss%s.\n",
  340.                len_cpu, cpu_nr+1,
  341.                len_num, mon_add_commas(buffer,
  342.                            sizeof(buffer),
  343.                            monitor->cpu_monitor[cpu_nr].event_count[mon_event_icache_miss]),
  344.                (monitor->cpu_monitor[cpu_nr].event_count[mon_event_icache_miss] == 1) ? "" : "es");
  345.  
  346.     {
  347.       long nr_insns = mon_get_number_of_insns(&monitor->cpu_monitor[cpu_nr]);
  348.       if (nr_insns > 0)
  349.     printf_filtered("CPU #%*d executed %*s instructions in total.\n",
  350.             len_cpu, cpu_nr+1,
  351.             len_num, mon_add_commas(buffer,
  352.                         sizeof(buffer),
  353.                         nr_insns));
  354.     }
  355.   }
  356.  
  357.   if (monitor->nr_cpus > 1)
  358.     printf_filtered("\nAll CPUs executed %s instructions in total.\n",
  359.             mon_add_commas(buffer, sizeof(buffer), total_insns));
  360.  
  361.   if (cpu_insns_second)
  362.     printf_filtered ("%sSimulator speed was %s instructions/second\n",
  363.              (monitor->nr_cpus > 1) ? "" : "\n",
  364.              mon_add_commas(buffer, sizeof(buffer), cpu_insns_second));
  365.   else if (cpu_time > 0.0)
  366.     printf_filtered ("%sSimulator executed for %.2f seconds\n",
  367.              (monitor->nr_cpus > 1) ? "" : "\n", cpu_time);
  368. }
  369.  
  370. #endif /* _MON_C_ */
  371.