Blame src/perfctr-2.6.x/usr.lib/misc.c

Packit Service a1973e
/* $Id: misc.c,v 1.20.2.1 2005/12/22 22:44:49 mikpe Exp $
Packit Service a1973e
 * Miscellaneous perfctr operations.
Packit Service a1973e
 *
Packit Service a1973e
 * Copyright (C) 1999-2004  Mikael Pettersson
Packit Service a1973e
 */
Packit Service a1973e
Packit Service a1973e
#include <errno.h>
Packit Service a1973e
#include <fcntl.h>
Packit Service a1973e
#include <sys/ioctl.h>
Packit Service a1973e
#include <stddef.h>
Packit Service a1973e
#include <stdio.h>
Packit Service a1973e
#include <stdlib.h>
Packit Service a1973e
#include <unistd.h>
Packit Service a1973e
#include "libperfctr.h"
Packit Service a1973e
#include "marshal.h"
Packit Service a1973e
#include "arch.h"
Packit Service a1973e
Packit Service a1973e
int _perfctr_abi_check_fd(int fd, unsigned int user_abi_version)
Packit Service a1973e
{
Packit Service a1973e
    unsigned int driver_abi_version;
Packit Service a1973e
    
Packit Service a1973e
    if( ioctl(fd, PERFCTR_ABI, &driver_abi_version) < 0 ) {
Packit Service a1973e
	perror("perfctr_abi_check");
Packit Service a1973e
	return -1;
Packit Service a1973e
    }
Packit Service a1973e
    if( (driver_abi_version ^ user_abi_version) & 0xFF00FF00 ) {
Packit Service a1973e
	fprintf(stderr, "Error: perfctr ABI major version mismatch: "
Packit Service a1973e
		"driver ABI 0x%08X, user ABI 0x%08X\n",
Packit Service a1973e
		driver_abi_version, user_abi_version);
Packit Service a1973e
	errno = EPROTO;
Packit Service a1973e
	return -1;
Packit Service a1973e
    }
Packit Service a1973e
    return 0;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int perfctr_info(int fd, struct perfctr_info *info)
Packit Service a1973e
{
Packit Service a1973e
    int err = perfctr_ioctl_r(fd, PERFCTR_INFO, info, &perfctr_info_sdesc);
Packit Service a1973e
    if( err < 0 )
Packit Service a1973e
	return err;
Packit Service a1973e
    perfctr_info_cpu_init(info);
Packit Service a1973e
    return 0;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int perfctr_get_info(struct perfctr_info *info)
Packit Service a1973e
{
Packit Service a1973e
    int fd, ret;
Packit Service a1973e
Packit Service a1973e
    fd = open("/dev/perfctr", O_RDONLY);
Packit Service a1973e
    if (fd < 0)
Packit Service a1973e
	return -1;
Packit Service a1973e
    ret = perfctr_info(fd, info);
Packit Service a1973e
    close(fd);
Packit Service a1973e
    return ret;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
struct perfctr_cpus_info *perfctr_cpus_info(int fd)
Packit Service a1973e
{
Packit Service a1973e
    struct perfctr_cpu_mask dummy;
Packit Service a1973e
    struct perfctr_cpus_info *info;
Packit Service a1973e
    unsigned int cpu_mask_bytes;
Packit Service a1973e
Packit Service a1973e
    dummy.nrwords = 0;
Packit Service a1973e
    if( ioctl(fd, PERFCTR_CPUS, &dummy) >= 0 ||
Packit Service a1973e
	errno != EOVERFLOW ||
Packit Service a1973e
	dummy.nrwords == 0 ) {
Packit Service a1973e
	perror("PERFCTR_CPUS");
Packit Service a1973e
	return NULL;
Packit Service a1973e
    }
Packit Service a1973e
    cpu_mask_bytes = offsetof(struct perfctr_cpu_mask, mask[dummy.nrwords]);
Packit Service a1973e
    info = malloc(sizeof(struct perfctr_cpus_info) + 2*cpu_mask_bytes);
Packit Service a1973e
    if( !info ) {
Packit Service a1973e
	perror("malloc");
Packit Service a1973e
	return NULL;
Packit Service a1973e
    }
Packit Service a1973e
    info->cpus = (struct perfctr_cpu_mask*)(info + 1);
Packit Service a1973e
    info->cpus->nrwords = dummy.nrwords;
Packit Service a1973e
    info->cpus_forbidden = (struct perfctr_cpu_mask*)((char*)(info + 1) + cpu_mask_bytes);
Packit Service a1973e
    info->cpus_forbidden->nrwords = dummy.nrwords;
Packit Service a1973e
    if( ioctl(fd, PERFCTR_CPUS, info->cpus) < 0 ||
Packit Service a1973e
	ioctl(fd, PERFCTR_CPUS_FORBIDDEN, info->cpus_forbidden) < 0 ) {
Packit Service a1973e
	perror("PERFCTR_CPUS");
Packit Service a1973e
	free(info);
Packit Service a1973e
	return NULL;
Packit Service a1973e
    }
Packit Service a1973e
    return info;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
void perfctr_info_print(const struct perfctr_info *info)
Packit Service a1973e
{
Packit Service a1973e
    static const char * const features[] = { "rdpmc", "rdtsc", "pcint" };
Packit Service a1973e
    int fi, comma;
Packit Service a1973e
Packit Service a1973e
    printf("abi_version\t\t0x%08X\n", info->abi_version);
Packit Service a1973e
    printf("driver_version\t\t%s\n", info->driver_version);
Packit Service a1973e
    printf("cpu_type\t\t%u (%s)\n", info->cpu_type, perfctr_info_cpu_name(info));
Packit Service a1973e
    printf("cpu_features\t\t%#x (", info->cpu_features);
Packit Service a1973e
    for(comma = 0, fi = 0; fi < sizeof features / sizeof features[0]; ++fi) {
Packit Service a1973e
	unsigned fmask = 1 << fi;
Packit Service a1973e
	if( info->cpu_features & fmask ) {
Packit Service a1973e
	    if( comma )
Packit Service a1973e
		printf(",");
Packit Service a1973e
	    printf("%s", features[fi]);
Packit Service a1973e
	    comma = 1;
Packit Service a1973e
	}
Packit Service a1973e
    }
Packit Service a1973e
    printf(")\n");
Packit Service a1973e
    printf("cpu_khz\t\t\t%u\n", info->cpu_khz);
Packit Service a1973e
    printf("tsc_to_cpu_mult\t\t%u%s\n",
Packit Service a1973e
	   info->tsc_to_cpu_mult,
Packit Service a1973e
	   info->tsc_to_cpu_mult ? "" : " (unspecified, assume 1)");
Packit Service a1973e
    printf("cpu_nrctrs\t\t%u\n", perfctr_info_nrctrs(info));
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
static void print_cpus(const struct perfctr_cpu_mask *cpus)
Packit Service a1973e
{
Packit Service a1973e
    unsigned int nrcpus, nr, i, cpumask, bitmask;
Packit Service a1973e
Packit Service a1973e
    printf("[");
Packit Service a1973e
    nrcpus = 0;
Packit Service a1973e
    for(i = 0; i < cpus->nrwords; ++i) {
Packit Service a1973e
	cpumask = cpus->mask[i];
Packit Service a1973e
	nr = i * 8 * sizeof(int);
Packit Service a1973e
	for(bitmask = 1; cpumask != 0; ++nr, bitmask <<= 1) {
Packit Service a1973e
	    if( cpumask & bitmask ) {
Packit Service a1973e
		cpumask &= ~bitmask;
Packit Service a1973e
		if( nrcpus )
Packit Service a1973e
		    printf(",");
Packit Service a1973e
		++nrcpus;
Packit Service a1973e
		printf("%u", nr);
Packit Service a1973e
	    }
Packit Service a1973e
	}
Packit Service a1973e
    }
Packit Service a1973e
    printf("], total: %u\n", nrcpus);
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
void perfctr_cpus_info_print(const struct perfctr_cpus_info *info)
Packit Service a1973e
{
Packit Service a1973e
    printf("cpus\t\t\t"); print_cpus(info->cpus);
Packit Service a1973e
    printf("cpus_forbidden\t\t"); print_cpus(info->cpus_forbidden);
Packit Service a1973e
}