xref: /minix3/minix/fs/procfs/util.c (revision f1abbce7257a5fbf50b3422d6dd5631fd0bf26a5)
1*f1abbce7SDavid van Moolenbroek /* ProcFS - util.c - utility functions */
2433d6423SLionel Sambuc 
3433d6423SLionel Sambuc #include "inc.h"
4433d6423SLionel Sambuc 
5*f1abbce7SDavid van Moolenbroek /*
6*f1abbce7SDavid van Moolenbroek  * Retrieve system load average information.
7433d6423SLionel Sambuc  */
8*f1abbce7SDavid van Moolenbroek int
procfs_getloadavg(struct load * loadavg,int nelem)9*f1abbce7SDavid van Moolenbroek procfs_getloadavg(struct load * loadavg, int nelem)
10*f1abbce7SDavid van Moolenbroek {
11433d6423SLionel Sambuc 	struct loadinfo loadinfo;
12433d6423SLionel Sambuc 	u32_t system_hz, ticks_per_slot;
13433d6423SLionel Sambuc 	int p, unfilled_ticks;
14*f1abbce7SDavid van Moolenbroek 	int h, slots, latest, slot;
15433d6423SLionel Sambuc 	int minutes[3] = { 1, 5, 15 };
16433d6423SLionel Sambuc 	ssize_t l;
17433d6423SLionel Sambuc 
18433d6423SLionel Sambuc 	if (nelem < 1) {
19433d6423SLionel Sambuc 		errno = ENOSPC;
20433d6423SLionel Sambuc 		return -1;
21433d6423SLionel Sambuc 	}
22433d6423SLionel Sambuc 
23433d6423SLionel Sambuc 	system_hz = sys_hz();
24433d6423SLionel Sambuc 
25433d6423SLionel Sambuc 	if ((l = sys_getloadinfo(&loadinfo)) != OK)
26433d6423SLionel Sambuc 		return -1;
27433d6423SLionel Sambuc 	if (nelem > 3)
28433d6423SLionel Sambuc 		nelem = 3;
29433d6423SLionel Sambuc 
30433d6423SLionel Sambuc 	/* How many ticks are missing from the newest-filled slot? */
31433d6423SLionel Sambuc 	ticks_per_slot = _LOAD_UNIT_SECS * system_hz;
32433d6423SLionel Sambuc 	unfilled_ticks =
33433d6423SLionel Sambuc 	    ticks_per_slot - (loadinfo.last_clock % ticks_per_slot);
34433d6423SLionel Sambuc 
35433d6423SLionel Sambuc 	for (p = 0; p < nelem; p++) {
36*f1abbce7SDavid van Moolenbroek 		latest = loadinfo.proc_last_slot;
37433d6423SLionel Sambuc 		slots = minutes[p] * 60 / _LOAD_UNIT_SECS;
38433d6423SLionel Sambuc 		loadavg[p].proc_load = 0;
39433d6423SLionel Sambuc 
40*f1abbce7SDavid van Moolenbroek 		/*
41*f1abbce7SDavid van Moolenbroek 		 * Add up the total number of process ticks for this number
42433d6423SLionel Sambuc 		 * of minutes (minutes[p]).  Start with the newest slot, which
43433d6423SLionel Sambuc 		 * is latest, and count back for the number of slots that
44433d6423SLionel Sambuc 		 * correspond to the right number of minutes.  Take wraparound
45433d6423SLionel Sambuc 		 * into account by calculating the index modulo _LOAD_HISTORY,
46433d6423SLionel Sambuc 		 * which is the number of slots of history kept.
47433d6423SLionel Sambuc 		 */
48433d6423SLionel Sambuc 		for (h = 0; h < slots; h++) {
49433d6423SLionel Sambuc 			slot = (latest - h + _LOAD_HISTORY) % _LOAD_HISTORY;
50433d6423SLionel Sambuc 			loadavg[p].proc_load +=
51433d6423SLionel Sambuc 			    loadinfo.proc_load_history[slot];
52f92baba7SEmmanuel Blot 			l += (ssize_t) loadinfo.proc_load_history[slot];
53433d6423SLionel Sambuc 		}
54433d6423SLionel Sambuc 
55*f1abbce7SDavid van Moolenbroek 		/*
56*f1abbce7SDavid van Moolenbroek 		 * The load average over this number of minutes is the number
57433d6423SLionel Sambuc 		 * of process-ticks divided by the number of ticks, not
58433d6423SLionel Sambuc 		 * counting the number of ticks the last slot hasn't been
59433d6423SLionel Sambuc 		 * around yet.
60433d6423SLionel Sambuc 		 */
61433d6423SLionel Sambuc 		loadavg[p].ticks = slots * ticks_per_slot - unfilled_ticks;
62433d6423SLionel Sambuc 	}
63433d6423SLionel Sambuc 
64433d6423SLionel Sambuc 	return nelem;
65433d6423SLionel Sambuc }
66