|
Packit |
577717 |
/* $Id: self.c,v 1.33 2005/11/07 01:48:13 mikpe Exp $
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* This test program illustrates how a process may use the
|
|
Packit |
577717 |
* Linux Performance-Monitoring Counters interface to
|
|
Packit |
577717 |
* monitor its own execution.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* The library uses mmap() to map the kernel's accumulated counter
|
|
Packit |
577717 |
* state into the process' address space.
|
|
Packit |
577717 |
* When perfctr_read_ctrs() is called, it uses the RDPMC and RDTSC
|
|
Packit |
577717 |
* instructions to get the current register values, and combines
|
|
Packit |
577717 |
* these with (sum,start) values found in the mapped-in kernel state.
|
|
Packit |
577717 |
* The resulting counts are then delivered to the application.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Copyright (C) 1999-2004 Mikael Pettersson
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
#include <stdio.h>
|
|
Packit |
577717 |
#include <stdlib.h>
|
|
Packit |
577717 |
#include <errno.h>
|
|
Packit |
577717 |
#include <string.h>
|
|
Packit |
577717 |
#include "libperfctr.h"
|
|
Packit |
577717 |
#include "arch.h"
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static struct vperfctr *self;
|
|
Packit |
577717 |
static struct perfctr_info info;
|
|
Packit |
577717 |
static struct vperfctr_control control;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
void do_init(void)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
struct perfctr_cpus_info *cpus_info;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
self = vperfctr_open();
|
|
Packit |
577717 |
if( !self ) {
|
|
Packit |
577717 |
perror("vperfctr_open");
|
|
Packit |
577717 |
exit(1);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if( vperfctr_info(self, &info) < 0 ) {
|
|
Packit |
577717 |
perror("vperfctr_info");
|
|
Packit |
577717 |
exit(1);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
cpus_info = vperfctr_cpus_info(self);
|
|
Packit |
577717 |
if( !cpus_info ) {
|
|
Packit |
577717 |
perror("vperfctr_cpus_info");
|
|
Packit |
577717 |
exit(1);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
printf("\nPerfCtr Info:\n");
|
|
Packit |
577717 |
perfctr_info_print(&info;;
|
|
Packit |
577717 |
perfctr_cpus_info_print(cpus_info);
|
|
Packit |
577717 |
free(cpus_info);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
void do_read(struct perfctr_sum_ctrs *sum)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* This is the preferred method for sampling all enabled counters.
|
|
Packit |
577717 |
* It doesn't return control data or current kernel-level state though.
|
|
Packit |
577717 |
* The control data can be retrieved using vperfctr_read_state().
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Alternatively you may call vperfctr_read_tsc() or vperfctr_read_pmc()
|
|
Packit |
577717 |
* to sample a single counter's value.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
vperfctr_read_ctrs(self, sum);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
void print_control(const struct perfctr_cpu_control *control)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
printf("\nControl used:\n");
|
|
Packit |
577717 |
perfctr_cpu_control_print(control);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
void do_enable(void)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
if( vperfctr_control(self, &control) < 0 ) {
|
|
Packit |
577717 |
perror("vperfctr_control");
|
|
Packit |
577717 |
exit(1);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
void do_print(const struct perfctr_sum_ctrs *before,
|
|
Packit |
577717 |
const struct perfctr_sum_ctrs *after)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
printf("\nFinal Sample:\n");
|
|
Packit |
577717 |
if( control.cpu_control.tsc_on )
|
|
Packit |
577717 |
printf("tsc\t\t\t%lld\n", after->tsc - before->tsc);
|
|
Packit |
577717 |
if( control.cpu_control.nractrs )
|
|
Packit |
577717 |
printf("pmc[0]\t\t\t%lld\n", after->pmc[0] - before->pmc[0]);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
unsigned fac(unsigned n)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
return (n < 2) ? 1 : n * fac(n-1);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
void do_fac(unsigned n)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
printf("\nfac(%u) == %u\n", n, fac(n));
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int main(void)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
struct perfctr_sum_ctrs before, after;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
do_init();
|
|
Packit |
577717 |
memset(&control, 0, sizeof control);
|
|
Packit |
577717 |
do_setup(&info, &control.cpu_control);
|
|
Packit |
577717 |
print_control(&control.cpu_control);
|
|
Packit |
577717 |
do_enable();
|
|
Packit |
577717 |
do_read(&before);
|
|
Packit |
577717 |
do_fac(15);
|
|
Packit |
577717 |
do_read(&after);
|
|
Packit |
577717 |
do_print(&before, &after);
|
|
Packit |
577717 |
return 0;
|
|
Packit |
577717 |
}
|