/*----------------------------------------------------------------------------*/

/*
 * Performance-Monitoring Counters Library, for Intel/AMD Processors and Linux
 * Author:  Don Heller, dheller@scl.ameslab.gov
 * Last revised:  19 January 2001
 */

/*----------------------------------------------------------------------------*/

/* measure nothing, for overhead estimation
 * print anything with at least 1 event in every trial
 * usage:  rabbit7 [options] [trials]
 * see also rabbit7.sh
 */

/*----------------------------------------------------------------------------*/

#include <pmc_lib.h>
#include <stdlib.h>
#include <math.h>

/*----------------------------------------------------------------------------*/

pmc_data_t t0, t1;
pmc_counter_t c;

int main(int argc, char * argv[])
{
  pmc_control_t Ctl = pmc_control_null;

  int e, i,j,k, out, trials = 1000;
  pmc_counter_t * a;

  /* initialize internal data structures, read command-line arguments */

  Ctl.stats = 1;	/* we need the min, mean and max */
  if (pmc_getargs(stderr, argv[0], &argc, &argv, &Ctl) == FALSE)
    { exit(RABBIT_FAILURE); }

  if (argc > 0) { trials = atoi(argv[0]); }

  // pmc_counter_init(&c, &Ctl);
  c = Ctl.counters[0];

  if (pmc_open(0) == FALSE)		/* open /dev/pmc */
    { exit(RABBIT_FAILURE); }

  /* for (out = 0; out < Ctl.num_counters; out++) { ... } */

  for (i = 0, out = 0; i < Ctl.event_pairs; i++) {
    for (j = 0; j < Ctl.replication; j++, out++) {
      a = &Ctl.counters[out];
      pmc_select(a);
      pmc_read(&t0); pmc_read(&t1);
      for (k = 0; k < trials; k++) {
	pmc_read(&t0);
	pmc_read(&t1);
	pmc_accumulate(a,&t1,&t0);
	pmc_accumulate_clock(&c,&t1,NULL);
      }
    }
  }

  pmc_close();				/* close /dev/pmc */

  printf("number of trials = %10d                       "
         "min     mean   max  std.dev\n", trials);

  printf("%-49s %5d %8.2f %5d %8.2f\n",
    "cycles",
    (int)pmc_min_cycles(&c),
    pmc_mean_cycles(&c),
    (int)pmc_max_cycles(&c),
    sqrt(pmc_variance_cycles(&c))
    );

  for (i = 0, out = 0; i < Ctl.event_pairs; i++) {
    for (j = 0; j < Ctl.replication; j++, out++) {
      a = &Ctl.counters[out];
      for (k = 0; k < pmc_event_counters; k++) {
	e = Ctl.events[i][k];
	if (pmc_min_events(a,k) > 0)
	  {
	    printf("0x%02x %3d %-40s %5d %8.2f %5d %8.2f\n",
		e, e, pmc_event_name(e,k),
		(int)pmc_min_events(a,k),
		pmc_mean_events(a,k),
		(int)pmc_max_events(a,k),
		sqrt(pmc_variance_events(a,k))
		);
	  }
      }
    }
  }

  printf("\n");

  exit(RABBIT_SUCCESS);
}

/*----------------------------------------------------------------------------*/
