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