Path: utzoo!utgpu!news-server.csri.toronto.edu!bonnie.concordia.ca!thunder.mcrcim.mcgill.edu!snorkelwacker.mit.edu!usc!sdd.hp.com!spool.mu.edu!uwm.edu!ux1.cso.uiuc.edu!kline From: kline@ux1.cso.uiuc.edu (Charley Kline) Newsgroups: comp.unix.aix Subject: Re: X11R4 xload Keywords: X11R4 Message-ID: <1991Jan31.195110.19739@ux1.cso.uiuc.edu> Date: 31 Jan 91 19:51:10 GMT References: <10133@ncar.ucar.edu> Organization: University of Illinois at Urbana Lines: 110 boote@bierstadt.scd.ucar.edu (Jeff W. Boote) writes: >Has anyone successfully ported the xload client from R4? If anyone out >there has a patchfile for it I would be most appreciative! If not, hints >and any information from attempts would be nice. AIX doesn't keep the load average information in the kernel, so you have to do the math yourself. Just replace the get_load.c module with the one below and you should be all set. You also need to include -lm in the libraries since GetLoadPoint() calls the exp() function. Good luck. ________________________________________________________________________ Charley Kline, KB9FFK, PP-ASEL c-kline@uiuc.edu University of Illinois Computing Services Packet: kb9ffk@w9yh 1304 W. Springfield Ave, Urbana IL 61801 (217) 333-3339 ----------------------------------------------------/begin included text /* * This version of this module (get_load.c) is specifically for the IBM * S/6000 AIX 3.1 platform. * * Charley Kline, University of Illinois Computing Services * c-kline@uiuc.edu */ #include #include #include #include #include #include #include #include #include struct nlist kernelnames[] = { {"sysinfo", 0, 0, 0, 0, 0}, {NULL, 0, 0, 0, 0, 0}, }; /* ARGSUSED */ void GetLoadPoint(w, closure, call_data) Widget w; /* unused */ caddr_t closure; /* unused */ caddr_t call_data; /* pointer to (double) return value */ { static double avenrun = 0.; double loadav; struct sysinfo si; static int rq_old = 0, ro_old = 0; static initted = 0; static int fd; double multiplier; double t; /* ** Do stuff we only need to do once per invocation, like opening ** the kmem file and fetching the parts of the symbol table. */ if (!initted) { initted = 1; knlist(kernelnames, 1, sizeof (struct nlist)); fd = open("/dev/kmem", O_RDONLY); if (fd < 0) { perror("kmem"); exit(1); } } /* ** Get the system info structure from the running kernel. */ lseek(fd, kernelnames[0].n_value, SEEK_SET); read(fd, &si, sizeof (struct sysinfo)); /* ** AIX doesn't keep the load average variables in the kernel; all ** we can get is the current number of runnable processes by ** observing the difference between the runque and runocc values ** in sysinfo, and dividing. Having done this, however, we can apply ** a TENEX-style exponential time-average to it by computing an ** averaging multiplier based on the sampling interval. This is then ** used to factor in the current number of runnable processes to our ** running load average. The result "looks right" when observed in ** conjunction with the process table and user activity. ** ** We subtract one from the number of running processes given us by ** the kernel because for some reason AIX always calls one of the ** kprocs "runnable" even though it uses very little CPU. Subtracting ** this out gives a load average near zero when the machine is mostly ** idle, which is more familiar to those of us who are used to ** bsd-style load averages. /cvk */ t = (double)(si.runocc - ro_old); loadav = (double)(si.runque - rq_old) / t - 1.0; rq_old = si.runque; ro_old = si.runocc; multiplier = exp(-t/60.); avenrun = multiplier * avenrun + (1.0 - multiplier) * loadav; /* DEBUG printf("%d %d %f %f %f\n", si.runque, si.runocc, t, loadav, avenrun); */ *(double *)call_data = avenrun; }