xref: /minix3/minix/fs/procfs/util.c (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
1*433d6423SLionel Sambuc /* ProcFS - util.c - by Alen Stojanov and David van Moolenbroek */
2*433d6423SLionel Sambuc 
3*433d6423SLionel Sambuc #include "inc.h"
4*433d6423SLionel Sambuc 
5*433d6423SLionel Sambuc /*===========================================================================*
6*433d6423SLionel Sambuc  *				procfs_getloadavg			     *
7*433d6423SLionel Sambuc  *===========================================================================*/
8*433d6423SLionel Sambuc int procfs_getloadavg(struct load *loadavg, int nelem)
9*433d6423SLionel Sambuc {
10*433d6423SLionel Sambuc 	/* Retrieve system load average information.
11*433d6423SLionel Sambuc 	 */
12*433d6423SLionel Sambuc 	struct loadinfo loadinfo;
13*433d6423SLionel Sambuc 	u32_t system_hz, ticks_per_slot;
14*433d6423SLionel Sambuc 	int p, unfilled_ticks;
15*433d6423SLionel Sambuc 	int minutes[3] = { 1, 5, 15 };
16*433d6423SLionel Sambuc 	ssize_t l;
17*433d6423SLionel Sambuc 
18*433d6423SLionel Sambuc 	if(nelem < 1) {
19*433d6423SLionel Sambuc 		errno = ENOSPC;
20*433d6423SLionel Sambuc 		return -1;
21*433d6423SLionel Sambuc 	}
22*433d6423SLionel Sambuc 
23*433d6423SLionel Sambuc 	system_hz = sys_hz();
24*433d6423SLionel Sambuc 
25*433d6423SLionel Sambuc 	if((l=sys_getloadinfo(&loadinfo)) != OK)
26*433d6423SLionel Sambuc 		return -1;
27*433d6423SLionel Sambuc 	if(nelem > 3)
28*433d6423SLionel Sambuc 		nelem = 3;
29*433d6423SLionel Sambuc 
30*433d6423SLionel Sambuc 	/* How many ticks are missing from the newest-filled slot? */
31*433d6423SLionel Sambuc 	ticks_per_slot = _LOAD_UNIT_SECS * system_hz;
32*433d6423SLionel Sambuc 	unfilled_ticks =
33*433d6423SLionel Sambuc 		ticks_per_slot - (loadinfo.last_clock % ticks_per_slot);
34*433d6423SLionel Sambuc 
35*433d6423SLionel Sambuc 	for(p = 0; p < nelem; p++) {
36*433d6423SLionel Sambuc 		int h, slots;
37*433d6423SLionel Sambuc 		int latest = loadinfo.proc_last_slot;
38*433d6423SLionel Sambuc 		slots = minutes[p] * 60 / _LOAD_UNIT_SECS;
39*433d6423SLionel Sambuc 		loadavg[p].proc_load = 0;
40*433d6423SLionel Sambuc 
41*433d6423SLionel Sambuc 		/* Add up the total number of process ticks for this number
42*433d6423SLionel Sambuc 		 * of minutes (minutes[p]). Start with the newest slot, which
43*433d6423SLionel Sambuc 		 * is latest, and count back for the number of slots that
44*433d6423SLionel Sambuc 		 * correspond to the right number of minutes. Take wraparound
45*433d6423SLionel Sambuc 		 * into account by calculating the index modulo _LOAD_HISTORY,
46*433d6423SLionel Sambuc 		 * which is the number of slots of history kept.
47*433d6423SLionel Sambuc 		 */
48*433d6423SLionel Sambuc 		for(h = 0; h < slots; h++) {
49*433d6423SLionel Sambuc 			int slot;
50*433d6423SLionel Sambuc 			slot = (latest - h + _LOAD_HISTORY) % _LOAD_HISTORY;
51*433d6423SLionel Sambuc 			loadavg[p].proc_load +=
52*433d6423SLionel Sambuc 				 loadinfo.proc_load_history[slot];
53*433d6423SLionel Sambuc 			l += (double) loadinfo.proc_load_history[slot];
54*433d6423SLionel Sambuc 		}
55*433d6423SLionel Sambuc 
56*433d6423SLionel Sambuc 		/* The load average over this number of minutes is the number
57*433d6423SLionel Sambuc 		 * of process-ticks divided by the number of ticks, not
58*433d6423SLionel Sambuc 		 * counting the number of ticks the last slot hasn't been
59*433d6423SLionel Sambuc 		 * around yet.
60*433d6423SLionel Sambuc 		 */
61*433d6423SLionel Sambuc 		loadavg[p].ticks = slots * ticks_per_slot - unfilled_ticks;
62*433d6423SLionel Sambuc 	}
63*433d6423SLionel Sambuc 
64*433d6423SLionel Sambuc 	return nelem;
65*433d6423SLionel Sambuc }
66