/* kern_resource.c 4.10 82/07/24 */ #include "../h/param.h" #include "../h/systm.h" #include "../h/acct.h" #include "../h/dir.h" #include "../h/user.h" #include "../h/inode.h" #include "../h/proc.h" #include "../h/seg.h" #include "../h/fs.h" struct inode *acctp; struct inode *savacctp; long acctlow = 2; /* stop accounting when < 2% data space left */ long accthigh = 4; /* resume when space risen to > 4% */ /* * Perform process accounting functions. */ sysacct() { register struct inode *ip; register struct a { char *fname; } *uap; uap = (struct a *)u.u_ap; if (suser()) { if (savacctp) { acctp = savacctp; savacctp = NULL; } if (uap->fname==NULL) { if (ip = acctp) { irele(ip); acctp = NULL; } return; } ip = namei(uchar, 0, 1); if(ip == NULL) return; if((ip->i_mode & IFMT) != IFREG) { u.u_error = EACCES; iput(ip); return; } if (acctp && (acctp->i_number != ip->i_number || acctp->i_dev != ip->i_dev)) irele(acctp); acctp = ip; iunlock(ip); } } struct acct acctbuf; /* * On exit, write a record on the accounting file. */ acct() { register i; register struct inode *ip; off_t siz; register struct acct *ap = &acctbuf; if (savacctp && savacctp->i_fs->fs_cstotal.cs_nbfree > accthigh * savacctp->i_fs->fs_dsize / 100) { acctp = savacctp; savacctp = NULL; printf("Accounting resumed\n"); } if ((ip=acctp)==NULL) return; if (acctp->i_fs->fs_cstotal.cs_nbfree < acctlow * acctp->i_fs->fs_dsize / 100) { savacctp = acctp; acctp = NULL; printf("Accounting suspended\n"); return; } ilock(ip); for (i=0; iac_comm); i++) ap->ac_comm[i] = u.u_comm[i]; ap->ac_utime = compress((long)u.u_vm.vm_utime); ap->ac_stime = compress((long)u.u_vm.vm_stime); ap->ac_etime = compress((long)(time - u.u_start)); ap->ac_btime = u.u_start; ap->ac_uid = u.u_ruid; ap->ac_gid = u.u_rgid; ap->ac_mem = 0; if (i = u.u_vm.vm_utime + u.u_vm.vm_stime) ap->ac_mem = (u.u_vm.vm_ixrss + u.u_vm.vm_idsrss) / i; ap->ac_io = compress((long)(u.u_vm.vm_inblk + u.u_vm.vm_oublk)); if (u.u_ttyp) ap->ac_tty = u.u_ttyd; else ap->ac_tty = NODEV; ap->ac_flag = u.u_acflag; siz = ip->i_size; u.u_offset = siz; u.u_base = (caddr_t)ap; u.u_count = sizeof(acctbuf); u.u_segflg = 1; u.u_error = 0; writei(ip); if(u.u_error) ip->i_size = siz; iunlock(ip); } /* * Produce a pseudo-floating point representation * with 3 bits base-8 exponent, 13 bits fraction. */ compress(t) register long t; { register exp = 0, round = 0; while (t >= 8192) { exp++; round = t&04; t >>= 3; } if (round) { t++; if (t >= 8192) { t >>= 3; exp++; } } return((exp<<13) + t); } vtimes() { register struct a { struct vtimes *par_vm; struct vtimes *ch_vm; } *uap = (struct a *)u.u_ap; if (uap->par_vm == 0) goto onlych; if (copyout((caddr_t)&u.u_vm, (caddr_t)uap->par_vm, sizeof(struct vtimes)) < 0) u.u_error = EFAULT; onlych: if (uap->ch_vm == 0) return; if (copyout((caddr_t)&u.u_cvm, (caddr_t)uap->ch_vm, sizeof(struct vtimes)) < 0) u.u_error = EFAULT; } vmsadd(vp, wp) register struct vtimes *vp, *wp; { vp->vm_utime += wp->vm_utime; vp->vm_stime += wp->vm_stime; vp->vm_nswap += wp->vm_nswap; vp->vm_idsrss += wp->vm_idsrss; vp->vm_ixrss += wp->vm_ixrss; if (vp->vm_maxrss < wp->vm_maxrss) vp->vm_maxrss = wp->vm_maxrss; vp->vm_majflt += wp->vm_majflt; vp->vm_minflt += wp->vm_minflt; vp->vm_inblk += wp->vm_inblk; vp->vm_oublk += wp->vm_oublk; }