Start converting to GPL v3+ (ref: ticket #23900)
[screen-lua.git] / src / loadav.c
blob430282036de4d61f95e8140b5a4dee4ee8e853e9
1 /* Copyright (c) 1993-2002
2 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
3 * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
4 * Copyright (c) 1987 Oliver Laumann
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3, or (at your option)
9 * any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program (see the file COPYING); if not, see
18 * http://www.gnu.org/licenses/, or contact Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
21 ****************************************************************
24 #include <sys/types.h>
25 #include <fcntl.h>
26 #ifdef ultrix
27 # include <sys/fixpoint.h>
28 #endif
30 /* mach stuff included here to prevent index macro conflict */
31 #ifdef NeXT
32 # include <sys/version.h>
33 # if KERNEL_MAJOR_VERSION > 2
34 # include <mach/mach.h>
35 # else
36 # include <mach.h>
37 # endif
38 #endif
40 #include "config.h"
41 #include "screen.h"
43 #include "extern.h"
45 #ifdef LOADAV
47 static int GetLoadav __P((void));
49 static LOADAV_TYPE loadav[LOADAV_NUM];
50 static int loadok;
54 /***************************************************************/
56 #if defined(linux) && !defined(LOADAV_DONE)
57 #define LOADAV_DONE
59 * This is the easy way. It relies in /proc being mounted.
60 * For the big and ugly way refer to previous screen version.
62 void
63 InitLoadav()
65 loadok = 1;
68 static int
69 GetLoadav()
71 FILE *fp;
72 char buf[128], *s;
73 int i;
74 double d, e;
76 if ((fp = secfopen("/proc/loadavg", "r")) == NULL)
77 return 0;
78 *buf = 0;
79 fgets(buf, sizeof(buf), fp);
80 fclose(fp);
81 /* can't use fscanf because the decimal point symbol depends on
82 * the locale but the kernel uses always '.'.
84 s = buf;
85 for (i = 0; i < (LOADAV_NUM > 3 ? 3 : LOADAV_NUM); i++)
87 d = e = 0;
88 while(*s == ' ')
89 s++;
90 if (*s == 0)
91 break;
92 for(;;)
94 if (*s == '.')
95 e = 1;
96 else if (*s >= '0' && *s <= '9')
98 d = d * 10 + (*s - '0');
99 if (e)
100 e *= 10;
102 else
103 break;
104 s++;
106 loadav[i] = e ? d / e : d;
108 return i;
110 #endif /* linux */
112 /***************************************************************/
114 #if defined(LOADAV_GETLOADAVG) && !defined(LOADAV_DONE)
115 #define LOADAV_DONE
116 void
117 InitLoadav()
119 loadok = 1;
122 static int
123 GetLoadav()
125 return getloadavg(loadav, LOADAV_NUM);
127 #endif
129 /***************************************************************/
131 #if defined(apollo) && !defined(LOADAV_DONE)
132 #define LOADAV_DONE
133 void
134 InitLoadav()
136 loadok = 1;
139 static int
140 GetLoadav()
142 proc1_$get_loadav(loadav);
143 return LOADAV_NUM;
145 #endif
147 /***************************************************************/
149 #if defined(NeXT) && !defined(LOADAV_DONE)
150 #define LOADAV_DONE
152 static processor_set_t default_set;
154 void
155 InitLoadav()
157 kern_return_t error;
159 error = processor_set_default(host_self(), &default_set);
160 if (error != KERN_SUCCESS)
161 mach_error("Error calling processor_set_default", error);
162 else
163 loadok = 1;
166 static int
167 GetLoadav()
169 unsigned int info_count;
170 struct processor_set_basic_info info;
171 host_t host;
173 info_count = PROCESSOR_SET_BASIC_INFO_COUNT;
174 if (processor_set_info(default_set, PROCESSOR_SET_BASIC_INFO, &host, (processor_set_info_t)&info, &info_count) != KERN_SUCCESS)
175 return 0;
176 loadav[0] = (float)info.load_average / LOAD_SCALE;
177 return 1;
179 #endif
181 /***************************************************************/
183 #if defined(sun) && defined(SVR4) && !defined(LOADAV_DONE)
184 #define LOADAV_DONE
186 #include <kstat.h>
188 static kstat_ctl_t *kc;
190 void
191 InitLoadav()
193 loadok = (kc = kstat_open()) != 0;
196 static int
197 GetLoadav()
199 kstat_t *ks;
200 kstat_named_t *avgs[3];
201 int i;
203 kstat_chain_update(kc);
204 if ((ks = kstat_lookup(kc, "unix", -1, "system_misc")) == 0 || kstat_read(kc, ks, (void *)0) == -1)
205 return (loadok = 0);
206 avgs[0] = kstat_data_lookup(ks, "avenrun_1min");
207 avgs[1] = kstat_data_lookup(ks, "avenrun_5min");
208 avgs[2] = kstat_data_lookup(ks, "avenrun_15min");
209 for (i = 0; i < 3; i++)
211 if (avgs[i] == 0 || avgs[i]->data_type != KSTAT_DATA_ULONG)
212 return (loadok = 0);
213 loadav[i] = avgs[i]->value.ul;
215 return 3;
218 #endif
220 /***************************************************************/
222 #if defined(__osf__) && defined(__alpha) && !defined(LOADAV_DONE)
223 #define LOADAV_DONE
225 struct rtentry; struct mbuf; /* shut up gcc on OSF/1 4.0 */
226 #include <sys/table.h>
228 void
229 InitLoadav()
231 loadok = 1;
234 static int
235 GetLoadav()
237 struct tbl_loadavg tbl;
238 int i;
240 if (table(TBL_LOADAVG, 0, &tbl, 1, sizeof(struct tbl_loadavg)) != 1)
241 return 0;
243 if (tbl.tl_lscale)
245 /* in long */
246 for (i = 0; i < LOADAV_NUM; i++)
247 loadav[i] = (double) tbl.tl_avenrun.l[i] / tbl.tl_lscale;
249 else
251 /* in double */
252 for (i = 0; i < LOADAV_NUM; i++)
253 loadav[i] = tbl.tl_avenrun.d[i];
255 return LOADAV_NUM;
257 #endif
259 /***************************************************************/
261 #if !defined(LOADAV_DONE)
263 * The old fashion way: open kernel and read avenrun
265 * Header File includes
268 # ifdef NLIST_STRUCT
269 # include <nlist.h>
270 # else
271 # include <a.out.h>
272 # endif
273 # ifndef NLIST_DECLARED
274 extern int nlist __P((char *, struct nlist *));
275 # endif
277 #ifdef LOADAV_USE_NLIST64
278 # define nlist nlist64
279 #endif
281 static struct nlist nl[2];
282 static int kmemf;
284 #ifdef _IBMR2
285 # define nlist(u,l) knlist(l,1,sizeof(*l))
286 #endif
288 void
289 InitLoadav()
291 debug("Init Kmem...\n");
292 if ((kmemf = open("/dev/kmem", O_RDONLY)) == -1)
293 return;
294 # if !defined(_AUX_SOURCE) && !defined(AUX)
295 # ifdef NLIST_NAME_UNION
296 nl[0].n_un.n_name = LOADAV_AVENRUN;
297 # else
298 nl[0].n_name = LOADAV_AVENRUN;
299 # endif
300 # else
301 strncpy(nl[0].n_name, LOADAV_AVENRUN, sizeof(nl[0].n_name));
302 # endif
303 debug2("Searching in %s for %s\n", LOADAV_UNIX, nl[0].n_name);
304 nlist(LOADAV_UNIX, nl);
305 if (nl[0].n_value == 0)
307 close(kmemf);
308 return;
310 # if 0 /* no longer needed (Al.Smith@aeschi.ch.eu.org) */
311 # ifdef sgi
312 nl[0].n_value &= (unsigned long)-1 >> 1; /* clear upper bit */
313 # endif /* sgi */
314 # endif
315 debug1("AvenrunSym found (0x%lx)!!\n", nl[0].n_value);
316 loadok = 1;
319 static int
320 GetLoadav()
322 if (lseek(kmemf, (off_t) nl[0].n_value, 0) == (off_t)-1)
323 return 0;
324 if (read(kmemf, (char *) loadav, sizeof(loadav)) != sizeof(loadav))
325 return 0;
326 return LOADAV_NUM;
328 #endif
330 /***************************************************************/
332 #ifndef FIX_TO_DBL
333 #define FIX_TO_DBL(l) ((double)(l) / LOADAV_SCALE)
334 #endif
336 void
337 AddLoadav(p)
338 char *p;
340 int i, j;
341 if (loadok == 0)
342 return;
343 j = GetLoadav();
344 for (i = 0; i < j; i++)
346 sprintf(p, " %2.2f" + !i, FIX_TO_DBL(loadav[i]));
347 p += strlen(p);
351 #endif /* LOADAV */