Ausam/sys/other/tune/ma.c
/*
* ma [a] [s] [u] [c] [r] default is s
*
* print a histogram of malloc usage for both swap and core.
*
* 'a' option: print information for all entries.
* default is off, i.e. only non-zero entries printed.
* 's' option: turns off histogram. prints only statistical summary.
* default is on.
* 'u' option: read previosly obtained values from
* "malloc.total". add these to values read from core
* write the latest obtained values to the file
* "malloc.total". always create file first.
* if update successful clear kernal core.
* default is no update
* 'r' option: combine prior stats with newly obtained values
* default is read
* 'c' option: update every 'NSEC' seconds
* no output given
* default is off but it implies update
*
*/
#define MAXS 100l /* max stars per line */
#define NSEC 600 /* seconds between updates */
error(s1,s2)
char *s1,*s2;
{
printf(s1,s2);
flush();
exit(-1);
}
double ldoub(i)
long i;
{
return(i);
}
double doub(i)
unsigned i;
{
return(i);
}
/************************/
unsigned mcore[2064];
unsigned mswap[258];
unsigned mdkmiss;
unsigned mcomiss;
unsigned mrdlen { sizeof mcore + sizeof mswap + sizeof mdkmiss + sizeof mcomiss };
/************************/
long dcore[2064];
long dswap[258];
long dkmiss;
long comiss;
unsigned rdlen { sizeof dcore + sizeof dswap + sizeof dkmiss + sizeof comiss };
/************************/
unsigned zero [ sizeof mcore + sizeof mswap + sizeof mdkmiss + sizeof mcomiss ];
int sflag 1;
int aflag 0;
int uflag 0;
int rflag 1;
int cflag 0;
char *mt "/etc/malloc.total";
struct {
char name[8];
int type;
char *value;
} nl[5] {
"_mcorec",0,0,
"_mdkrec",0,0, /* assumed contigous with above */
"_mcomiss",0,0, /* assumed contigous with above */
"_mdkmiss",0,0, /* assumed contigous with above */
"",0,0
};
main(argc,argv)
char **argv;
int argc;
{
register mem,mtfd,i;
extern fout;
fout = dup(1);
/*
* get options
*/
for(argv++; --argc; argv++)
if(**argv == 'a') aflag++;
else if(**argv == 's') sflag=0;
else if(**argv == 'u') uflag++;
else if(**argv == 'c') cflag++,uflag++;
else if(**argv == 'r') rflag=0;
nlist("/unix",nl);
if( (nl[0].type==0) || (nl[1].type==0) || (nl[2].type==0) || (nl[3].type==0) ) error("namelist error\n");
mem = open("/dev/kmem", ( uflag ? 2 : 0 ) );
if( mem<0 ) error("can't open /dev/kmem\n");
if( uflag || rflag ) {
if( (mtfd=open(mt,0)) < 0 )
error(" can't open %s\n",mt);
if( read(mtfd,dcore,rdlen)!=rdlen)
error(" read error %s\n",mt);
close(mtfd);
}
loop:
disable();
lseek( mem, 0, nl[0].value, 0);
if( read( mem, mcore, mrdlen)!=mrdlen ) error("core read error\n");
for(i=0;i<2064;i++) dcore[i] =+ mcore[i];
for(i=0;i< 258;i++) dswap[i] =+ mswap[i];
dkmiss =+ mdkmiss;
comiss =+ mcomiss;
if( uflag ){
if( (mtfd=creat(mt,0600)) < 0 )
error(" can't create %s\n",mt);
if( write(mtfd,dcore,rdlen)!=rdlen)
error(" write error %s\n",mt);
close(mtfd);
if( !cflag ) {
printf(" malloc.total updated\n");
flush();
}
lseek( mem, 0, nl[0].value, 0);
if( write( mem, zero, mrdlen)!=mrdlen ) error("core write error\n");
if( !cflag ) {
printf(" kernal core cleared\n");
flush();
}
}
enable();
if( cflag ) {
sleep(NSEC);
goto loop;
}
prit(dcore,2064,"core",16,comiss);
prit(dswap,258,"swap",2,dkmiss);
}
prit(aray , nelt, s, nk, misses)
long aray[];
int nelt,nk;
char *s;
long misses;
{
register i,j,k; long scale;
double num ; double sum ; double nkb;
double dev;
extern double sqrt();
dev = sum = num = 0.0;
nkb = nk;
for(i= -1;aray[++i]==0;);
for(j=nelt;aray[--j]==0;);
scale = 0;
for(k=i;k<=j;k++) {
if(aray[k] > scale ) scale = aray[k];
sum = sum + ldoub(aray[k]) * doub(k);
num = num + ldoub(aray[k]);
dev = dev + ldoub(aray[k]) * doub(k) * doub(k);
}
if ( num==0 ) {
printf("\014\n %s *** no allocations *** \n",s);
flush();
return;
}
printf("\014\n %s \n",s);
if( !sflag)
for(;i<=j;i++){
if((aray[i] == 0) && (!aflag)) continue;
printf("%4d %6.3fk %5ld | ",i,i/nkb,aray[i]);
k = aray[i];
k = (k*MAXS)/scale;
while((k--)>0) putchar('*');
putchar('\n');
}
printf("\n mean = %5.1f %6.1fk sample = %5.0f \n",sum/num,(sum/num)/nkb,num);
dev = sqrt( (dev - sum*sum/num)/num );
printf("\n standard deviation = %5.1f %6.1fk \n\n",
dev,(dev)/nkb);
if( misses )
printf("\tmisses = %ld %5.1f%%\n",misses,misses*100./num);
flush();
}
int s1,s2,s3;
disable()
{
s1 = signal(1,1); s2 = signal(2,1); s3 = signal(3,1);
}
enable()
{
signal(1,s1); signal(2,s2); signal(3,s3);
}