Merge branch 'scripting-python' (early part) into screen-scripting-soc
[screen-lua.git] / src / loadav.c
blob770010c36852ced803baae8d56a29cc39c368736
1 /* Copyright (c) 2008, 2009
2 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
3 * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
4 * Micah Cowan (micah@cowan.name)
5 * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net)
6 * Copyright (c) 1993-2002, 2003, 2005, 2006, 2007
7 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
8 * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
9 * Copyright (c) 1987 Oliver Laumann
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3, or (at your option)
14 * any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program (see the file COPYING); if not, see
23 * http://www.gnu.org/licenses/, or contact Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
26 ****************************************************************
29 #include <sys/types.h>
30 #include <fcntl.h>
31 #ifdef ultrix
32 # include <sys/fixpoint.h>
33 #endif
35 /* mach stuff included here to prevent index macro conflict */
36 #ifdef NeXT
37 # include <sys/version.h>
38 # if KERNEL_MAJOR_VERSION > 2
39 # include <mach/mach.h>
40 # else
41 # include <mach.h>
42 # endif
43 #endif
45 #include "config.h"
46 #include "screen.h"
48 #include "extern.h"
50 #ifdef LOADAV
52 static int GetLoadav __P((void));
54 static LOADAV_TYPE loadav[LOADAV_NUM];
55 static int loadok;
59 /***************************************************************/
61 #if defined(linux) && !defined(LOADAV_DONE)
62 #define LOADAV_DONE
64 * This is the easy way. It relies in /proc being mounted.
65 * For the big and ugly way refer to previous screen version.
67 void
68 InitLoadav()
70 loadok = 1;
73 static int
74 GetLoadav()
76 FILE *fp;
77 char buf[128], *s;
78 int i;
79 double d, e;
81 if ((fp = secfopen("/proc/loadavg", "r")) == NULL)
82 return 0;
83 *buf = 0;
84 fgets(buf, sizeof(buf), fp);
85 fclose(fp);
86 /* can't use fscanf because the decimal point symbol depends on
87 * the locale but the kernel uses always '.'.
89 s = buf;
90 for (i = 0; i < (LOADAV_NUM > 3 ? 3 : LOADAV_NUM); i++)
92 d = e = 0;
93 while(*s == ' ')
94 s++;
95 if (*s == 0)
96 break;
97 for(;;)
99 if (*s == '.')
100 e = 1;
101 else if (*s >= '0' && *s <= '9')
103 d = d * 10 + (*s - '0');
104 if (e)
105 e *= 10;
107 else
108 break;
109 s++;
111 loadav[i] = e ? d / e : d;
113 return i;
115 #endif /* linux */
117 /***************************************************************/
119 #if defined(LOADAV_GETLOADAVG) && !defined(LOADAV_DONE)
120 #define LOADAV_DONE
121 void
122 InitLoadav()
124 loadok = 1;
127 static int
128 GetLoadav()
130 return getloadavg(loadav, LOADAV_NUM);
132 #endif
134 /***************************************************************/
136 #if defined(apollo) && !defined(LOADAV_DONE)
137 #define LOADAV_DONE
138 void
139 InitLoadav()
141 loadok = 1;
144 static int
145 GetLoadav()
147 proc1_$get_loadav(loadav);
148 return LOADAV_NUM;
150 #endif
152 /***************************************************************/
154 #if defined(NeXT) && !defined(LOADAV_DONE)
155 #define LOADAV_DONE
157 static processor_set_t default_set;
159 void
160 InitLoadav()
162 kern_return_t error;
164 error = processor_set_default(host_self(), &default_set);
165 if (error != KERN_SUCCESS)
166 mach_error("Error calling processor_set_default", error);
167 else
168 loadok = 1;
171 static int
172 GetLoadav()
174 unsigned int info_count;
175 struct processor_set_basic_info info;
176 host_t host;
178 info_count = PROCESSOR_SET_BASIC_INFO_COUNT;
179 if (processor_set_info(default_set, PROCESSOR_SET_BASIC_INFO, &host, (processor_set_info_t)&info, &info_count) != KERN_SUCCESS)
180 return 0;
181 loadav[0] = (float)info.load_average / LOAD_SCALE;
182 return 1;
184 #endif
186 /***************************************************************/
188 #if defined(sun) && defined(SVR4) && !defined(LOADAV_DONE)
189 #define LOADAV_DONE
191 #include <kstat.h>
193 static kstat_ctl_t *kc;
195 void
196 InitLoadav()
198 loadok = (kc = kstat_open()) != 0;
201 static int
202 GetLoadav()
204 kstat_t *ks;
205 kstat_named_t *avgs[3];
206 int i;
208 kstat_chain_update(kc);
209 if ((ks = kstat_lookup(kc, "unix", -1, "system_misc")) == 0 || kstat_read(kc, ks, (void *)0) == -1)
210 return (loadok = 0);
211 avgs[0] = kstat_data_lookup(ks, "avenrun_1min");
212 avgs[1] = kstat_data_lookup(ks, "avenrun_5min");
213 avgs[2] = kstat_data_lookup(ks, "avenrun_15min");
214 for (i = 0; i < 3; i++)
216 if (avgs[i] == 0 || avgs[i]->data_type != KSTAT_DATA_ULONG)
217 return (loadok = 0);
218 loadav[i] = avgs[i]->value.ul;
220 return 3;
223 #endif
225 /***************************************************************/
227 #if defined(__osf__) && defined(__alpha) && !defined(LOADAV_DONE)
228 #define LOADAV_DONE
230 struct rtentry; struct mbuf; /* shut up gcc on OSF/1 4.0 */
231 #include <sys/table.h>
233 void
234 InitLoadav()
236 loadok = 1;
239 static int
240 GetLoadav()
242 struct tbl_loadavg tbl;
243 int i;
245 if (table(TBL_LOADAVG, 0, &tbl, 1, sizeof(struct tbl_loadavg)) != 1)
246 return 0;
248 if (tbl.tl_lscale)
250 /* in long */
251 for (i = 0; i < LOADAV_NUM; i++)
252 loadav[i] = (double) tbl.tl_avenrun.l[i] / tbl.tl_lscale;
254 else
256 /* in double */
257 for (i = 0; i < LOADAV_NUM; i++)
258 loadav[i] = tbl.tl_avenrun.d[i];
260 return LOADAV_NUM;
262 #endif
264 /***************************************************************/
266 #if !defined(LOADAV_DONE)
268 * The old fashion way: open kernel and read avenrun
270 * Header File includes
273 # ifdef NLIST_STRUCT
274 # include <nlist.h>
275 # else
276 # include <a.out.h>
277 # endif
278 # ifndef NLIST_DECLARED
279 extern int nlist __P((char *, struct nlist *));
280 # endif
282 #ifdef LOADAV_USE_NLIST64
283 # define nlist nlist64
284 #endif
286 static struct nlist nl[2];
287 static int kmemf;
289 #ifdef _IBMR2
290 # define nlist(u,l) knlist(l,1,sizeof(*l))
291 #endif
293 void
294 InitLoadav()
296 debug("Init Kmem...\n");
297 if ((kmemf = open("/dev/kmem", O_RDONLY)) == -1)
298 return;
299 # if !defined(_AUX_SOURCE) && !defined(AUX)
300 # ifdef NLIST_NAME_UNION
301 nl[0].n_un.n_name = LOADAV_AVENRUN;
302 # else
303 nl[0].n_name = LOADAV_AVENRUN;
304 # endif
305 # else
306 strncpy(nl[0].n_name, LOADAV_AVENRUN, sizeof(nl[0].n_name));
307 # endif
308 debug2("Searching in %s for %s\n", LOADAV_UNIX, nl[0].n_name);
309 nlist(LOADAV_UNIX, nl);
310 if (nl[0].n_value == 0)
312 close(kmemf);
313 return;
315 # if 0 /* no longer needed (Al.Smith@aeschi.ch.eu.org) */
316 # ifdef sgi
317 nl[0].n_value &= (unsigned long)-1 >> 1; /* clear upper bit */
318 # endif /* sgi */
319 # endif
320 debug1("AvenrunSym found (0x%lx)!!\n", nl[0].n_value);
321 loadok = 1;
324 static int
325 GetLoadav()
327 if (lseek(kmemf, (off_t) nl[0].n_value, 0) == (off_t)-1)
328 return 0;
329 if (read(kmemf, (char *) loadav, sizeof(loadav)) != sizeof(loadav))
330 return 0;
331 return LOADAV_NUM;
333 #endif
335 /***************************************************************/
337 #ifndef FIX_TO_DBL
338 #define FIX_TO_DBL(l) ((double)(l) / LOADAV_SCALE)
339 #endif
341 void
342 AddLoadav(p)
343 char *p;
345 int i, j;
346 if (loadok == 0)
347 return;
348 j = GetLoadav();
349 for (i = 0; i < j; i++)
351 sprintf(p, " %2.2f" + !i, FIX_TO_DBL(loadav[i]));
352 p += strlen(p);
356 #endif /* LOADAV */