Blame src/perfctr-2.7.x/examples/self/self.c

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
}