1
0
Files
irix-657m-src/eoe/cmd/profiler/prfpr.c
2022-09-29 17:59:04 +03:00

314 lines
7.3 KiB
C

/* Copyright (c) 1984 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
/* #ident "@(#)profil-3b5:prfpr.c 1.6" */
#ident "$Revision: 1.12 $"
/*
* prfpr - print profiler log files
*
* Format of profiler file:
* prfmax (int) # of symbols
* nprocs (int) max # of cpus
* symbols (prfmax symaddr_t) symbol addresses
* timestamp (time_t) time stamp
* cpuid (int)
* ctrs (prfmax ints) - actual counters
* cpuid (int)
* .
* .
* timestamp
*/
#include <fcntl.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
#include <stdlib.h>
#include <unistd.h>
#include "prf.h"
static struct profile {
time_t p_date; /* time stamp of record */
int *p_cpuid; /* cpuid */
int *p_ctr; /* profiler counter values */
} p[2];
static int prfmax; /* actual number of text symbols */
static int nprocs; /* # of processors worth of info */
static double cutoff = 1.0; /* percentage cutoff */
static double pc;
static double spc = 0.0;
static symaddr_t *t;
static char *namelist = "/unix";
static char *logfile;
static int *sum, *osum;
typedef struct {
char *name;
symaddr_t addr;
} syment_t;
static int symcnt; /* number of symbols */
static int symlistsize; /* size of malloc'ed memory for list */
static syment_t *symlist; /* list of symbols */
static syment_t *symnext; /* next free slot */
static void shtime(time_t *);
static void listinit(void);
static void listadd(char *, symaddr_t);
static void printname(syment_t *);
static syment_t *search(symaddr_t);
extern int rdsymtab(int, void (*)(char *, symaddr_t));
extern int rdelfsymtab(int, void (*)(char *, symaddr_t));
int
main(int argc, char **argv)
{
register int ff, log, i, j;
register int nsamp;
register int icutoff;
register int *nctr, *octr;
int filesampsz;
int fd;
syment_t *sp;
int dwarfsyms;
switch(argc) {
case 4:
namelist = argv[3];
case 3:
cutoff = atof(argv[2]);
case 2:
logfile = argv[1];
break;
default:
error("usage: prfpr file [ cutoff [ namelist ] ]");
}
if ((log = open(logfile, O_RDONLY)) < 0)
error("cannot open data file");
if((fd = open(namelist, O_RDONLY)) < 0)
error("cannot open namelist file");
if (cutoff > 100.0 || cutoff < 0.0)
error("invalid cutoff percentage");
if (read(log, &prfmax, sizeof prfmax) != sizeof prfmax || prfmax == 0)
error("bad data file (no prfmax)");
if (read(log, &nprocs, sizeof nprocs) != sizeof nprocs || nprocs == 0)
error("bad data file (no nprocs)");
/* alloc space for addresses */
if ((t = (symaddr_t *) malloc(prfmax * sizeof(symaddr_t))) == 0)
error("cannot allocate space for addresses");
filesampsz = prfmax * (int) sizeof(int);
/* alloc space for counters - 2 sets */
if ((p[0].p_ctr = (int *) malloc(nprocs * filesampsz)) == 0)
error("cannot allocate space for counters");
if ((p[1].p_ctr = (int *) malloc(nprocs * filesampsz)) == 0)
error("cannot allocate space for counters");
/* alloc space for cpuids - 2 sets */
if ((p[0].p_cpuid = (int *) malloc(nprocs * sizeof(int))) == 0)
error("cannot allocate space for counters");
if ((p[1].p_cpuid = (int *) malloc(nprocs * sizeof(int))) == 0)
error("cannot allocate space for counters");
/* alloc sum counters */
if ((osum = (int *) malloc(nprocs * sizeof(int))) == 0)
error("cannot allocate space for sums");
if ((sum = (int *) malloc(nprocs * sizeof(int))) == 0)
error("cannot allocate space for sums");
if (read(log, t, prfmax * sizeof (symaddr_t))
!= prfmax * sizeof (symaddr_t))
error("cannot read profile addresses");
ff = 0;
for (j = 0; j < nprocs; j++)
osum[j] = sum[j] = 0;
if (read(log, &p[!ff].p_date, sizeof(time_t)) != sizeof(time_t))
error("error reading time stamp");
/* calc total # of samples */
for (j = 0; j < nprocs; j++) {
nctr = &(p[!ff].p_ctr[j * prfmax]);
/* read in first buffer full */
if (read(log, &p[!ff].p_cpuid[j], sizeof(int)) != sizeof(int))
error("error reading cpuid");
if (read(log, nctr, filesampsz) != filesampsz)
error("error reading counters");
for (i = 0; i < prfmax; i++)
osum[j] += *nctr++;
}
system("uname -a");
listinit();
dwarfsyms = rdsymtab(fd, listadd);
if( rdelfsymtab(fd, listadd) && dwarfsyms ) {
printf("%s: unable to load dwarf/mdebug or elf symbol \
table information\n", argv[0]);
exit(1);
}
/* integerize cutoff - we keep 100* percentage
* 0 -> ALL samples
*/
icutoff = (int)(100 * cutoff);
for(;;) {
for (j = 0; j < nprocs; j++)
sum[j] = 0;
if (read(log, &p[ff].p_date, sizeof(time_t)) != sizeof(time_t)) {
break;
}
printf("\n");
shtime(&p[!ff].p_date);
shtime(&p[ff].p_date);
for (j = 0; j < nprocs; j++) {
nctr = &(p[ff].p_ctr[j * prfmax]);
if (read(log, &p[ff].p_cpuid[j], sizeof(int)) != sizeof(int))
error("error reading cpuid");
if (read(log, nctr, filesampsz) != filesampsz)
break;
for (i = 0; i < prfmax; i++)
sum[j] += *nctr++;
if (sum[j] == osum[j]) {
printf("CPU %d no samples\n\n", p[ff].p_cpuid[j]);
continue;
}
if (p[ff].p_cpuid[j] != p[!ff].p_cpuid[j])
error("CPU #'s changed!");
printf("\nCPU %d - %d total samples; cutoff %f\n",
p[ff].p_cpuid[j], sum[j] - osum[j], cutoff);
nctr = &(p[ff].p_ctr[j * prfmax]);
octr = &(p[!ff].p_ctr[j * prfmax]);
for (i = 0; i < prfmax; i++) {
nsamp = *nctr++ - *octr++;
if (nsamp == 0)
continue;
pc = 10000.0 * nsamp;
pc = pc / (sum[j] - osum[j]);
if(pc > icutoff || icutoff == 0) {
sp = search(t[i]);
if(sp == 0)
printf("unknown ");
else {
printname(sp);
printf(" ");
}
printf("%.4f\n", pc/100);
spc += pc;
}
}
}
ff = !ff;
for (j = 0; j < nprocs; j++)
osum[j] = sum[j];
printf("Total %.2f\n", spc/100);
spc = 0.0;
}
exit(0);
/* NOTREACHED */
}
void
error(char *s)
{
printf("error: %s\n", s);
exit(1);
}
static void
shtime(time_t *l)
{
register struct tm *t;
if(*l == (time_t) 0) {
printf("initialization\n");
return;
}
t = localtime(l);
printf("%02.2d/%02.2d/%02.2d %02.2d:%02.2d\n", t->tm_mon + 1,
t->tm_mday, t->tm_year%100, t->tm_hour, t->tm_min);
}
#define LISTINCR 6000
static void
listinit(void)
{
symlist = (syment_t *)malloc(LISTINCR * sizeof (syment_t));
if (symlist == NULL)
error("cannot allocate memory");
symnext = symlist;
symcnt = 0;
symlistsize = LISTINCR;
}
/* ARGSUSED */
static void
listadd(char *name, symaddr_t addr)
{
if (symcnt >= symlistsize) {
symlistsize += LISTINCR;
symlist = (syment_t *)
realloc(symlist, symlistsize * sizeof(syment_t));
if (symlist == NULL)
error("cannot allocate memory");
symnext = &symlist[symcnt];
}
symnext->name = name;
symnext->addr = addr;
symnext++;
symcnt++;
}
static syment_t *
search(symaddr_t addr)
{
register syment_t *sp;
register syment_t *save;
symaddr_t value;
value = 0;
save = 0;
for(sp = symlist; sp < &symlist[symcnt]; sp++) {
if(sp->addr <= addr && sp->addr > value) {
value = sp->addr;
save = sp;
}
}
return(save);
}
int
list_repeated(symaddr_t addr)
{
register syment_t *sp;
for(sp = symlist; sp < &symlist[symcnt]; sp++)
if(sp->addr == addr )
return 1;
return 0;
}
static void
printname(syment_t *ent)
{
printf("%-24.24s ", ent->name);
}