/*
* Copyright (c) 1986 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*
* @(#)kern_acct.c 3.1 (2.11BSD) 1999/4/29
*
* This module is a shadow of its former self. This comment:
*
* SHOULD REPLACE THIS WITH A DRIVER THAT CAN BE READ TO SIMPLIFY.
*
* is all that is left of the original kern_acct.c module.
*/
#include "param.h"
#include "systm.h"
#include "user.h"
#include "msgbuf.h"
#include "kernel.h"
#include "acct.h"
comp_t compress();
int Acctthresh = 10;
/*
* On exit, write a record on the accounting file.
*/
acct()
{
struct acct acctbuf;
register struct acct *ap = &acctbuf;
static short acctcnt = 0;
bcopy(u.u_comm, ap->ac_comm, sizeof(acctbuf.ac_comm));
/*
* The 'user' and 'system' times need to be converted from 'hz' (linefrequency)
* clockticks to the AHZ pseudo-tick unit of measure. The elapsed time is
* converted from seconds to AHZ ticks.
*/
ap->ac_utime = compress(((u_long)u.u_ru.ru_utime * AHZ) / hz);
ap->ac_stime = compress(((u_long)u.u_ru.ru_stime * AHZ) / hz);
ap->ac_etime = compress((u_long)(time.tv_sec - u.u_start) * AHZ);
ap->ac_btime = u.u_start;
ap->ac_uid = u.u_ruid;
ap->ac_gid = u.u_rgid;
ap->ac_mem = (u.u_dsize+u.u_ssize) / 16; /* fast ctok() */
/*
* Section 3.9 of the 4.3BSD book says that I/O is measured in 1/AHZ units too.
*/
ap->ac_io = compress((u_long)(u.u_ru.ru_inblock+u.u_ru.ru_oublock)*AHZ);
if (u.u_ttyp)
ap->ac_tty = u.u_ttyd;
else
ap->ac_tty = NODEV;
ap->ac_flag = u.u_acflag;
/*
* Not a lot that can be done if logwrt fails so ignore any errors. Every
* few (10 by default) commands call the wakeup routine. This isn't perfect
* but does cut down the overhead of issuing a wakeup to the accounting daemon
* every single accounting record. The threshold is settable via sysctl(8)
*/
logwrt(ap, sizeof (*ap), logACCT);
if (++acctcnt >= Acctthresh)
{
logwakeup(logACCT);
acctcnt = 0;
}
}
/*
* Raise exponent and drop bits off the right of the mantissa until the
* mantissa fits. If we run out of exponent space, return max value (all
* one bits). With AHZ set to 64 this is good for close to 8.5 years:
* (8191 * (1 << (3*7)) / 64 / 60 / 60 / 24 / 365 ~= 8.5)
*/
#define MANTSIZE 13 /* 13 bit mantissa. */
#define EXPSIZE 3 /* Base 8 (3 bit) exponent. */
comp_t
compress(mant)
u_long mant;
{
register int exp;
for (exp = 0; exp < (1 << EXPSIZE); exp++, mant >>= EXPSIZE)
if (mant < (1L << MANTSIZE))
return(mant | (exp << MANTSIZE));
return(~0);
}