get_load.c revision a8bb11d0
1fd0c672fSmrg/*
2fd0c672fSmrg
3fd0c672fSmrgCopyright (c) 1989  X Consortium
4fd0c672fSmrg
5fd0c672fSmrgPermission is hereby granted, free of charge, to any person obtaining
6fd0c672fSmrga copy of this software and associated documentation files (the
7fd0c672fSmrg"Software"), to deal in the Software without restriction, including
8fd0c672fSmrgwithout limitation the rights to use, copy, modify, merge, publish,
9fd0c672fSmrgdistribute, sublicense, and/or sell copies of the Software, and to
10fd0c672fSmrgpermit persons to whom the Software is furnished to do so, subject to
11fd0c672fSmrgthe following conditions:
12fd0c672fSmrg
13fd0c672fSmrgThe above copyright notice and this permission notice shall be included
14fd0c672fSmrgin all copies or substantial portions of the Software.
15fd0c672fSmrg
16fd0c672fSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17fd0c672fSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18fd0c672fSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19fd0c672fSmrgIN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
20fd0c672fSmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21fd0c672fSmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22fd0c672fSmrgOTHER DEALINGS IN THE SOFTWARE.
23fd0c672fSmrg
24fd0c672fSmrgExcept as contained in this notice, the name of the X Consortium shall
25fd0c672fSmrgnot be used in advertising or otherwise to promote the sale, use or
26fd0c672fSmrgother dealings in this Software without prior written authorization
27fd0c672fSmrgfrom the X Consortium.
28fd0c672fSmrg
29fd0c672fSmrg*/
30fd0c672fSmrg
31fd0c672fSmrg/*
32fd0c672fSmrg * get_load - get system load
33fd0c672fSmrg *
34fd0c672fSmrg * Authors:  Many and varied...
35fd0c672fSmrg *
36fd0c672fSmrg * Call InitLoadPoint() to initialize.
37fd0c672fSmrg * GetLoadPoint() is a callback for the StripChart widget.
38fd0c672fSmrg */
39fd0c672fSmrg
40fd0c672fSmrg#ifdef HAVE_CONFIG_H
41fd0c672fSmrg# include "config.h"
42fd0c672fSmrg#endif
43fd0c672fSmrg
44fd0c672fSmrg#include <X11/Xos.h>
45fd0c672fSmrg#include <X11/Intrinsic.h>
46fd0c672fSmrg#include <X11/Xlocale.h>
47fd0c672fSmrg#include <stdio.h>
48fd0c672fSmrg#include <stdlib.h>
49fd0c672fSmrg#include "xload.h"
50fd0c672fSmrg
51fd0c672fSmrg#if defined(__CYGWIN__)
52a8bb11d0Smrg#define WIN32_LEAN_AND_MEAN
53fd0c672fSmrg#include <windows.h>
54fd0c672fSmrgtypedef struct {
55fd0c672fSmrg  DWORD stat;
56fd0c672fSmrg  union {
57fd0c672fSmrg    LONG vLong;
58fd0c672fSmrg    double vDouble;
59fd0c672fSmrg    LONGLONG vLongLong;
60fd0c672fSmrg    void *string;
61fd0c672fSmrg  } u;
62fd0c672fSmrg} COUNTER;
63fd0c672fSmrgstatic HANDLE query;
64fd0c672fSmrgstatic HANDLE counter;
65fd0c672fSmrgstatic HINSTANCE hdll;
66fd0c672fSmrgstatic long (__stdcall *pdhopen)(LPCSTR, DWORD, HANDLE);
67fd0c672fSmrgstatic long (__stdcall *pdhaddcounter)(HANDLE, LPCSTR, DWORD, HANDLE*);
68fd0c672fSmrgstatic long (__stdcall *pdhcollectquerydata)(HANDLE);
69fd0c672fSmrgstatic long (__stdcall *pdhgetformattedcountervalue)(HANDLE, DWORD, LPDWORD, COUNTER*);
70fd0c672fSmrg#define CYGWIN_PERF
71a8bb11d0Smrgvoid InitLoadPoint(void)
72fd0c672fSmrg{
73fd0c672fSmrg  long ret;
74fd0c672fSmrg  hdll=LoadLibrary("pdh.dll");
75fd0c672fSmrg  if (!hdll) exit(-1);
76fd0c672fSmrg  pdhopen=(void*)GetProcAddress(hdll, "PdhOpenQueryA");
77fd0c672fSmrg  if (!pdhopen) exit(-1);
78fd0c672fSmrg  pdhaddcounter=(void*)GetProcAddress(hdll, "PdhAddCounterA");
79fd0c672fSmrg  if (!pdhaddcounter) exit(-1);
80fd0c672fSmrg  pdhcollectquerydata=(void*)GetProcAddress(hdll, "PdhCollectQueryData");
81fd0c672fSmrg  if (!pdhcollectquerydata) exit(-1);
82fd0c672fSmrg  pdhgetformattedcountervalue=(void*)GetProcAddress(hdll, "PdhGetFormattedCounterValue");
83fd0c672fSmrg  if (!pdhgetformattedcountervalue) exit(-1);
84fd0c672fSmrg  ret = pdhopen( NULL , 0, &query );
85fd0c672fSmrg  if (ret!=0) exit(-1);
86fd0c672fSmrg  ret = pdhaddcounter(query, "\\Processor(_Total)\\% Processor Time", 0, &counter);
87fd0c672fSmrg  if (ret!=0) exit(-1);
88fd0c672fSmrg}
89a8bb11d0Smrgvoid GetLoadPoint(
90a8bb11d0Smrg     Widget  w,              /* unused */
91a8bb11d0Smrg     XtPointer    closure,        /* unused */
92a8bb11d0Smrg     XtPointer    call_data)      /* pointer to (double) return value */
93fd0c672fSmrg{
94fd0c672fSmrg  double *loadavg = (double *)call_data;
95fd0c672fSmrg  COUNTER fmtvalue;
96fd0c672fSmrg  long ret;
97fd0c672fSmrg  *loadavg = 0.0;
98fd0c672fSmrg  ret = pdhcollectquerydata(query);
99fd0c672fSmrg  if (ret!=0) return;
100fd0c672fSmrg  ret = pdhgetformattedcountervalue(counter, 0x200, NULL, &fmtvalue);
101fd0c672fSmrg  if (ret!=0) return;
102fd0c672fSmrg  *loadavg = (fmtvalue.u.vDouble-0.01)/100.0;
103fd0c672fSmrg}
104fd0c672fSmrg#else
105fd0c672fSmrg
106fd0c672fSmrg
107fd0c672fSmrg#if defined(att) || defined(QNX4)
108fd0c672fSmrg#define LOADSTUB
109fd0c672fSmrg#endif
110fd0c672fSmrg
111fd0c672fSmrg#ifndef LOADSTUB
112fd0c672fSmrg#if !defined(linux) && !defined(__UNIXOS2__) && !defined(__GLIBC__)
113fd0c672fSmrg#include <nlist.h>
114fd0c672fSmrg#endif /* !linux && ... */
115fd0c672fSmrg#endif /* LOADSTUB */
116fd0c672fSmrg
117fd0c672fSmrg#if defined(MOTOROLA) && defined(SYSV)
118fd0c672fSmrg#include <sys/sysinfo.h>
119fd0c672fSmrg#endif
120fd0c672fSmrg
121fd0c672fSmrg#ifdef CSRG_BASED
122fd0c672fSmrg#include <sys/param.h>
123fd0c672fSmrg#endif
124fd0c672fSmrg
125fd0c672fSmrg#if defined(umips) || (defined(ultrix) && defined(mips))
126fd0c672fSmrg#include <sys/fixpoint.h>
127fd0c672fSmrg#endif
128fd0c672fSmrg
129fd0c672fSmrg#if  defined(CRAY) || defined(AIXV3)
130fd0c672fSmrg#include <sys/param.h>
131fd0c672fSmrg#define word word_t
132fd0c672fSmrg#include <sys/sysinfo.h>
133fd0c672fSmrg#undef word
134fd0c672fSmrg#undef n_type
135fd0c672fSmrg#define n_type n_value
136fd0c672fSmrg#endif	/* CRAY */
137fd0c672fSmrg
138fd0c672fSmrg#ifdef sequent
139fd0c672fSmrg#include <sys/vm.h>
140fd0c672fSmrg#endif /* sequent */
141fd0c672fSmrg
142fd0c672fSmrg
143fd0c672fSmrg#ifdef hcx
144fd0c672fSmrg#include <sys/param.h>
145fd0c672fSmrg#endif /* hcx */
146fd0c672fSmrg
147fd0c672fSmrg#if defined(UTEK) || defined(alliant) || (defined(MOTOROLA) && defined(SVR4))
148fd0c672fSmrg#define FSCALE	100.0
149fd0c672fSmrg#endif
150fd0c672fSmrg
151fd0c672fSmrg#ifdef sequent
152fd0c672fSmrg#define FSCALE	1000.0
153fd0c672fSmrg#endif
154fd0c672fSmrg
155fd0c672fSmrg#ifdef sgi
156fd0c672fSmrg#define FSCALE	1024.0
157fd0c672fSmrg#endif
158fd0c672fSmrg
159fd0c672fSmrg#if defined(sony) && OSMAJORVERSION == 4
160fd0c672fSmrg#ifdef mips
161fd0c672fSmrg#include <sys/fixpoint.h>
162fd0c672fSmrg#else
163fd0c672fSmrg#include <sys/param.h>
164fd0c672fSmrg#endif
165fd0c672fSmrg#endif
166fd0c672fSmrg
167fd0c672fSmrg#ifdef __osf__
168fd0c672fSmrg/*
169fd0c672fSmrg * Use the table(2) interface; it doesn't require setuid root.
170fd0c672fSmrg *
171fd0c672fSmrg * Select 0, 1, or 2 for 5, 30, or 60 second load averages.
172fd0c672fSmrg */
173fd0c672fSmrg#ifndef WHICH_AVG
174fd0c672fSmrg#define WHICH_AVG 1
175fd0c672fSmrg#endif
176fd0c672fSmrg#include <sys/table.h>
177fd0c672fSmrg#endif
178fd0c672fSmrg
179fd0c672fSmrg#ifdef SVR4
180fd0c672fSmrg#ifndef FSCALE
181fd0c672fSmrg#define FSCALE	(1 << 8)
182fd0c672fSmrg#endif
183fd0c672fSmrg#endif
184fd0c672fSmrg
185fd0c672fSmrg#ifdef X_NOT_POSIX
186fd0c672fSmrgextern long lseek();
187fd0c672fSmrg#endif
188fd0c672fSmrg
189a8bb11d0Smrgstatic void xload_error(const char *, const char *) _X_NORETURN;
190fd0c672fSmrg
191fd0c672fSmrg
192fd0c672fSmrg#if defined(SYSV) && defined(i386)
193fd0c672fSmrg/*
194fd0c672fSmrg * inspired by 'avgload' by John F. Haugh II
195fd0c672fSmrg */
196fd0c672fSmrg#include <sys/param.h>
197fd0c672fSmrg#include <sys/buf.h>
198fd0c672fSmrg#include <sys/immu.h>
199fd0c672fSmrg#include <sys/region.h>
200fd0c672fSmrg#include <sys/var.h>
201fd0c672fSmrg#include <sys/proc.h>
202fd0c672fSmrg#define KERNEL_FILE "/unix"
203fd0c672fSmrg#define KMEM_FILE "/dev/kmem"
204fd0c672fSmrg#define VAR_NAME "v"
205fd0c672fSmrg#define PROC_NAME "proc"
206fd0c672fSmrg#define BUF_NAME "buf"
207fd0c672fSmrg#define DECAY 0.8
208fd0c672fSmrgstruct nlist namelist[] = {
209fd0c672fSmrg  {VAR_NAME},
210fd0c672fSmrg  {PROC_NAME},
211fd0c672fSmrg  {BUF_NAME},
212fd0c672fSmrg  {0},
213fd0c672fSmrg};
214fd0c672fSmrg
215fd0c672fSmrgstatic int kmem;
216fd0c672fSmrgstatic struct var v;
217fd0c672fSmrgstatic struct proc *p;
218fd0c672fSmrgstatic XtPointer first_buf, last_buf;
219fd0c672fSmrg
220fd0c672fSmrgvoid InitLoadPoint()				/* SYSV386 version */
221fd0c672fSmrg{
222fd0c672fSmrg    int i;
223fd0c672fSmrg
224fd0c672fSmrg    nlist( KERNEL_FILE, namelist);
225fd0c672fSmrg
226fd0c672fSmrg    for (i=0; namelist[i].n_name; i++)
227fd0c672fSmrg	if (namelist[i].n_value == 0)
228fd0c672fSmrg	    xload_error("cannot get name list from", KERNEL_FILE);
229fd0c672fSmrg
230fd0c672fSmrg    if ((kmem = open(KMEM_FILE, O_RDONLY)) < 0)
231fd0c672fSmrg	xload_error("cannot open", KMEM_FILE);
232fd0c672fSmrg
233fd0c672fSmrg    if (lseek(kmem, namelist[0].n_value, 0) == -1)
234fd0c672fSmrg	xload_error("cannot seek", VAR_NAME);
235fd0c672fSmrg
236fd0c672fSmrg    if (read(kmem, &v, sizeof(v)) != sizeof(v))
237fd0c672fSmrg	xload_error("cannot read", VAR_NAME);
238fd0c672fSmrg
239fd0c672fSmrg    if ((p=(struct proc *)malloc(v.v_proc*sizeof(*p))) == NULL)
240fd0c672fSmrg	xload_error("cannot allocat space for", PROC_NAME);
241fd0c672fSmrg
242fd0c672fSmrg    first_buf = (XtPointer) namelist[2].n_value;
243fd0c672fSmrg    last_buf  = (char *)first_buf + v.v_buf * sizeof(struct buf);
244fd0c672fSmrg}
245fd0c672fSmrg
246fd0c672fSmrg/* ARGSUSED */
247fd0c672fSmrgvoid GetLoadPoint( w, closure, call_data )	/* SYSV386 version */
248fd0c672fSmrgWidget	w;		/* unused */
249fd0c672fSmrgXtPointer	closure;	/* unused */
250fd0c672fSmrgXtPointer	call_data;	/* pointer to (double) return value */
251fd0c672fSmrg{
252fd0c672fSmrg    double *loadavg = (double *)call_data;
253fd0c672fSmrg    static double avenrun = 0.0;
254fd0c672fSmrg    int i, nproc, size;
255fd0c672fSmrg
256fd0c672fSmrg    (void) lseek(kmem, namelist[0].n_value, 0);
257fd0c672fSmrg    (void) read(kmem, &v, sizeof(v));
258fd0c672fSmrg
259fd0c672fSmrg    size = (struct proc *)v.ve_proc - (struct proc *)namelist[1].n_value;
260fd0c672fSmrg
261fd0c672fSmrg    (void) lseek(kmem, namelist[1].n_value, 0);
262fd0c672fSmrg    (void) read(kmem, p, size * sizeof(struct proc));
263fd0c672fSmrg
264fd0c672fSmrg    for (nproc = 0, i=0; i<size; i++)
265fd0c672fSmrg	  if ((p[i].p_stat == SRUN) ||
266fd0c672fSmrg	      (p[i].p_stat == SIDL) ||
267fd0c672fSmrg	      (p[i].p_stat == SXBRK) ||
268fd0c672fSmrg	      (p[i].p_stat == SSLEEP && (p[i].p_pri < PZERO) &&
269fd0c672fSmrg	       (p[i].p_wchan >= (char *)first_buf) && (p[i].p_wchan < (char *)last_buf)))
270fd0c672fSmrg	    nproc++;
271fd0c672fSmrg
272fd0c672fSmrg    /* update the load average using a decay filter */
273fd0c672fSmrg    avenrun = DECAY * avenrun + nproc * (1.0 - DECAY);
274fd0c672fSmrg    *loadavg = avenrun;
275fd0c672fSmrg
276fd0c672fSmrg    return;
277fd0c672fSmrg}
278fd0c672fSmrg#else /* not (SYSV && i386) */
279fd0c672fSmrg
280fd0c672fSmrg#if defined(linux) || (defined(__FreeBSD_kernel__) && defined(__GLIBC__))
281fd0c672fSmrg
28248e69166Smrgvoid InitLoadPoint(void)
283fd0c672fSmrg{
284fd0c672fSmrg      return;
285fd0c672fSmrg}
286fd0c672fSmrg
28748e69166Smrgvoid GetLoadPoint(
28848e69166Smrg    Widget	w,		/* unused */
28948e69166Smrg    XtPointer	closure,	/* unused */
29048e69166Smrg    XtPointer	call_data)      /* pointer to (double) return value */
291fd0c672fSmrg{
292fd0c672fSmrg      static int fd = -1;
293fd0c672fSmrg      int n;
294fd0c672fSmrg      char buf[10] = {0, };
295fd0c672fSmrg#ifndef X_LOCALE
296fd0c672fSmrg      char *dp;
297fd0c672fSmrg      static char ldp = 0;
298fd0c672fSmrg#endif
299fd0c672fSmrg
300fd0c672fSmrg
301fd0c672fSmrg      if (fd < 0)
302fd0c672fSmrg      {
303fd0c672fSmrg              if (fd == -2 ||
304fd0c672fSmrg                  (fd = open("/proc/loadavg", O_RDONLY)) < 0)
305fd0c672fSmrg              {
306fd0c672fSmrg                      fd = -2;
307fd0c672fSmrg                      *(double *)call_data = 0.0;
308fd0c672fSmrg                      return;
309fd0c672fSmrg              }
310fd0c672fSmrg#ifndef X_LOCALE
311fd0c672fSmrg	      ldp = *localeconv()->decimal_point;
312fd0c672fSmrg#endif
313fd0c672fSmrg      }
314fd0c672fSmrg      else
315fd0c672fSmrg              lseek(fd, 0, 0);
316fd0c672fSmrg
317fd0c672fSmrg      if ((n = read(fd, buf, sizeof(buf)-1)) > 0) {
318fd0c672fSmrg#ifndef X_LOCALE
319fd0c672fSmrg	  if (ldp != '.')
320fd0c672fSmrg	      while ((dp = memchr(buf,'.',sizeof(buf)-1)) != NULL) {
321fd0c672fSmrg		  *(char *)dp = ldp;
322fd0c672fSmrg	      }
323fd0c672fSmrg
324fd0c672fSmrg#endif
325fd0c672fSmrg	  if (sscanf(buf, "%lf", (double *)call_data) == 1)
326fd0c672fSmrg	      return;
327fd0c672fSmrg      }
328fd0c672fSmrg
329fd0c672fSmrg
330fd0c672fSmrg      *(double *)call_data = 0.0;     /* temporary hiccup */
331fd0c672fSmrg
332fd0c672fSmrg      return;
333fd0c672fSmrg}
334fd0c672fSmrg
335fd0c672fSmrg#else /* linux */
336fd0c672fSmrg
337fd0c672fSmrg#ifdef __GNU__
338fd0c672fSmrg
339fd0c672fSmrg#include <mach.h>
340fd0c672fSmrg
341fd0c672fSmrgstatic processor_set_t default_set;
342fd0c672fSmrg
34348e69166Smrgvoid InitLoadPoint(void)
344fd0c672fSmrg{
345fd0c672fSmrg  if (processor_set_default (mach_host_self (), &default_set) != KERN_SUCCESS)
346fd0c672fSmrg    xload_error("cannot get processor_set_default", "");
347fd0c672fSmrg}
348fd0c672fSmrg
349fd0c672fSmrg/* ARGSUSED */
35048e69166Smrgvoid GetLoadPoint(
35148e69166Smrg    Widget	w,		/* unused */
35248e69166Smrg    XtPointer	closure,	/* unused */
35348e69166Smrg    XtPointer	call_data)	/* pointer to (double) return value */
354fd0c672fSmrg{
355fd0c672fSmrg  host_t host;
356fd0c672fSmrg  struct processor_set_basic_info info;
357fd0c672fSmrg  unsigned info_count;
358fd0c672fSmrg
359fd0c672fSmrg  info_count = PROCESSOR_SET_BASIC_INFO_COUNT;
360fd0c672fSmrg  if (processor_set_info (default_set, PROCESSOR_SET_BASIC_INFO, &host,
361fd0c672fSmrg			  (processor_set_info_t) &info, &info_count)
362fd0c672fSmrg      != KERN_SUCCESS)
363fd0c672fSmrg    {
364fd0c672fSmrg      InitLoadPoint();
365fd0c672fSmrg      info.load_average = 0;
366fd0c672fSmrg    }
367fd0c672fSmrg
368fd0c672fSmrg  *(double *)call_data = info.load_average * 1000 / LOAD_SCALE;
369fd0c672fSmrg
370fd0c672fSmrg  return;
371fd0c672fSmrg}
372fd0c672fSmrg
373fd0c672fSmrg#else /* __GNU__ */
374fd0c672fSmrg
37548e69166Smrg#ifdef __APPLE__
376fd0c672fSmrg
377fd0c672fSmrg#include <mach/mach.h>
378fd0c672fSmrg
379fd0c672fSmrgstatic mach_port_t host_priv_port;
380fd0c672fSmrg
38148e69166Smrgvoid InitLoadPoint(void)
382fd0c672fSmrg{
383fd0c672fSmrg    host_priv_port = mach_host_self();
384fd0c672fSmrg}
385fd0c672fSmrg
386fd0c672fSmrg/* ARGSUSED */
38748e69166Smrgvoid GetLoadPoint(
38848e69166Smrg    Widget	w,		/* unused */
38948e69166Smrg    XtPointer	closure,	/* unused */
39048e69166Smrg    XtPointer	call_data)	/* pointer to (double) return value */
391fd0c672fSmrg{
392fd0c672fSmrg    double *loadavg = (double *)call_data;
393fd0c672fSmrg
394fd0c672fSmrg    struct host_load_info load_data;
395fd0c672fSmrg    int host_count;
396fd0c672fSmrg    kern_return_t kr;
397fd0c672fSmrg
398fd0c672fSmrg    host_count = sizeof(load_data)/sizeof(integer_t);
399fd0c672fSmrg    kr = host_statistics(host_priv_port, HOST_LOAD_INFO,
400fd0c672fSmrg                        (host_info_t)&load_data, &host_count);
401fd0c672fSmrg    if (kr != KERN_SUCCESS)
402fd0c672fSmrg        xload_error("cannot get host statistics", "");
403fd0c672fSmrg    *loadavg = (double)load_data.avenrun[0]/LOAD_SCALE;
404fd0c672fSmrg    return;
405fd0c672fSmrg}
406fd0c672fSmrg
40748e69166Smrg#else /* __APPLE__ */
408fd0c672fSmrg
409fd0c672fSmrg#ifdef LOADSTUB
410fd0c672fSmrg
411fd0c672fSmrgvoid InitLoadPoint()
412fd0c672fSmrg{
413fd0c672fSmrg}
414fd0c672fSmrg
415fd0c672fSmrg/* ARGSUSED */
416fd0c672fSmrgvoid GetLoadPoint( w, closure, call_data )
417fd0c672fSmrg     Widget	w;		/* unused */
418fd0c672fSmrg     XtPointer	closure;	/* unused */
419fd0c672fSmrg     XtPointer	call_data;	/* pointer to (double) return value */
420fd0c672fSmrg{
421fd0c672fSmrg	*(double *)call_data = 1.0;
422fd0c672fSmrg}
423fd0c672fSmrg
424fd0c672fSmrg#else /* not LOADSTUB */
425fd0c672fSmrg
426fd0c672fSmrg#ifdef __osf__
427fd0c672fSmrg
428fd0c672fSmrgvoid InitLoadPoint()
429fd0c672fSmrg{
430fd0c672fSmrg}
431fd0c672fSmrg
432fd0c672fSmrg/*ARGSUSED*/
433fd0c672fSmrgvoid GetLoadPoint( w, closure, call_data )
434fd0c672fSmrg     Widget   w;              /* unused */
435fd0c672fSmrg     XtPointer  closure;        /* unused */
436fd0c672fSmrg     XtPointer  call_data;      /* pointer to (double) return value */
437fd0c672fSmrg{
438fd0c672fSmrg    double *loadavg = (double *)call_data;
439fd0c672fSmrg    struct tbl_loadavg load_data;
440fd0c672fSmrg
441fd0c672fSmrg    if (table(TBL_LOADAVG, 0, (char *)&load_data, 1, sizeof(load_data)) < 0)
442fd0c672fSmrg	xload_error("error reading load average", "");
443fd0c672fSmrg    *loadavg = (load_data.tl_lscale == 0) ?
444fd0c672fSmrg	load_data.tl_avenrun.d[WHICH_AVG] :
445fd0c672fSmrg	load_data.tl_avenrun.l[WHICH_AVG] / (double)load_data.tl_lscale;
446fd0c672fSmrg}
447fd0c672fSmrg
448fd0c672fSmrg#else /* not __osf__ */
449fd0c672fSmrg
450fd0c672fSmrg#ifdef __QNXNTO__
451fd0c672fSmrg#include <time.h>
452fd0c672fSmrg#include <sys/neutrino.h>
453fd0c672fSmrgstatic _Uint64t          nto_idle = 0, nto_idle_last = 0;
454fd0c672fSmrgstatic  int       nto_idle_id;
455fd0c672fSmrgstatic  struct timespec nto_now, nto_last;
456fd0c672fSmrg
457fd0c672fSmrgvoid
45848e69166SmrgInitLoadPoint(void)
459fd0c672fSmrg{
460fd0c672fSmrg  nto_idle_id = ClockId(1, 1); /* Idle thread */
461fd0c672fSmrg  ClockTime(nto_idle_id, NULL, &nto_idle_last);
462fd0c672fSmrg  clock_gettime( CLOCK_REALTIME, &nto_last);
463fd0c672fSmrg}
464fd0c672fSmrg
465fd0c672fSmrg/* ARGSUSED */
466fd0c672fSmrgvoid
46748e69166SmrgGetLoadPoint(			/* QNX NTO version */
46848e69166Smrg    Widget	w,		/* unused */
46948e69166Smrg    XtPointer	closure,	/* unused */
47048e69166Smrg    XtPointer	call_data)	/* pointer to (double) return value */
471fd0c672fSmrg{
472fd0c672fSmrg    double *loadavg = (double *)call_data;
473fd0c672fSmrg    double timediff;
474fd0c672fSmrg    double temp = 0.0;
475fd0c672fSmrg
476fd0c672fSmrg    ClockTime(nto_idle_id, NULL, &nto_idle);
477fd0c672fSmrg    clock_gettime( CLOCK_REALTIME, &nto_now);
478fd0c672fSmrg    timediff = 1000000000.0 * (nto_now.tv_sec - nto_last.tv_sec)
479fd0c672fSmrg               + (nto_now.tv_nsec - nto_last.tv_nsec);
480fd0c672fSmrg    temp = 1.0 - (nto_idle-nto_idle_last)/timediff;
481fd0c672fSmrg    *loadavg = temp >= 0 ? temp : 0;
482fd0c672fSmrg    nto_idle_last = nto_idle;
483fd0c672fSmrg    nto_last = nto_now;
484fd0c672fSmrg}
485fd0c672fSmrg#else /* not __QNXNTO__ */
486fd0c672fSmrg
487fd0c672fSmrg#ifdef __bsdi__
488fd0c672fSmrg#include <kvm.h>
489fd0c672fSmrg
490fd0c672fSmrgstatic struct nlist nl[] = {
491fd0c672fSmrg  { "_averunnable" },
492fd0c672fSmrg#define X_AVERUNNABLE 0
493fd0c672fSmrg  { "_fscale" },
494fd0c672fSmrg#define X_FSCALE      1
495fd0c672fSmrg  { "" },
496fd0c672fSmrg};
497fd0c672fSmrgstatic kvm_t *kd;
498fd0c672fSmrgstatic int fscale;
499fd0c672fSmrg
50048e69166Smrgvoid InitLoadPoint(void)
501fd0c672fSmrg{
502fd0c672fSmrg  fixpt_t averunnable[3];  /* unused really */
503fd0c672fSmrg
504fd0c672fSmrg  if ((kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, NULL)) == NULL)
505fd0c672fSmrg    xload_error("can't open kvm files", "");
506fd0c672fSmrg
507fd0c672fSmrg  if (kvm_nlist(kd, nl) != 0)
508fd0c672fSmrg    xload_error("can't read name list", "");
509fd0c672fSmrg
510fd0c672fSmrg  if (kvm_read(kd, (off_t)nl[X_AVERUNNABLE].n_value, (char *)averunnable,
511fd0c672fSmrg	       sizeof(averunnable)) != sizeof(averunnable))
512fd0c672fSmrg    xload_error("couldn't obtain _averunnable variable", "");
513fd0c672fSmrg
514fd0c672fSmrg  if (kvm_read(kd, (off_t)nl[X_FSCALE].n_value, (char *)&fscale,
515fd0c672fSmrg	       sizeof(fscale)) != sizeof(fscale))
516fd0c672fSmrg    xload_error("couldn't obtain _fscale variable", "");
517fd0c672fSmrg
518fd0c672fSmrg  return;
519fd0c672fSmrg}
520fd0c672fSmrg
52148e69166Smrgvoid GetLoadPoint(
52248e69166Smrg     Widget	w,		/* unused */
52348e69166Smrg     XtPointer	closure,	/* unused */
52448e69166Smrg    XtPointer	call_data)	/* ptr to (double) return value */
525fd0c672fSmrg{
526fd0c672fSmrg  double *loadavg = (double *)call_data;
527fd0c672fSmrg  fixpt_t t;
528fd0c672fSmrg
529fd0c672fSmrg  if (kvm_read(kd, (off_t)nl[X_AVERUNNABLE].n_value, (char *)&t,
530fd0c672fSmrg	       sizeof(t)) != sizeof(t))
531fd0c672fSmrg    xload_error("couldn't obtain load average", "");
532fd0c672fSmrg
533fd0c672fSmrg  *loadavg = (double)t/fscale;
534fd0c672fSmrg
535fd0c672fSmrg  return;
536fd0c672fSmrg}
537fd0c672fSmrg
538fd0c672fSmrg#else /* not __bsdi__ */
539a8bb11d0Smrg#if defined(HAVE_GETLOADAVG)
540fd0c672fSmrg#include <stdlib.h>
541a8bb11d0Smrg#ifdef HAVE_SYS_LOADAVG_H
542a8bb11d0Smrg#include <sys/loadavg.h>	/* Solaris definition of getloadavg */
543a8bb11d0Smrg#endif
544fd0c672fSmrg
545fd0c672fSmrgvoid InitLoadPoint()
546fd0c672fSmrg{
547fd0c672fSmrg}
548fd0c672fSmrg
549fd0c672fSmrgvoid GetLoadPoint(w, closure, call_data)
550fd0c672fSmrg     Widget w;          /* unused */
551fd0c672fSmrg     XtPointer closure;   /* unused */
552fd0c672fSmrg     XtPointer call_data; /* ptr to (double) return value */
553fd0c672fSmrg{
554fd0c672fSmrg  double *loadavg = (double *)call_data;
555fd0c672fSmrg
556fd0c672fSmrg  if (getloadavg(loadavg, 1) < 0)
557fd0c672fSmrg    xload_error("couldn't obtain load average", "");
558fd0c672fSmrg}
559fd0c672fSmrg
560a8bb11d0Smrg#else /* not HAVE_GETLOADAVG */
561fd0c672fSmrg
562fd0c672fSmrg#ifndef KMEM_FILE
563fd0c672fSmrg#define KMEM_FILE "/dev/kmem"
564fd0c672fSmrg#endif
565fd0c672fSmrg
566fd0c672fSmrg#ifndef KERNEL_FILE
567fd0c672fSmrg
568fd0c672fSmrg#ifdef alliant
569fd0c672fSmrg#define KERNEL_FILE "/vmunix"
570fd0c672fSmrg#endif /* alliant */
571fd0c672fSmrg
572fd0c672fSmrg#ifdef CRAY
573fd0c672fSmrg#define KERNEL_FILE "/unicos"
574fd0c672fSmrg#endif /* CRAY */
575fd0c672fSmrg
576fd0c672fSmrg#ifdef hpux
577fd0c672fSmrg#define KERNEL_FILE "/hp-ux"
578fd0c672fSmrg#endif /* hpux */
579fd0c672fSmrg
580fd0c672fSmrg
581fd0c672fSmrg#ifdef umips
582fd0c672fSmrg# ifdef SYSTYPE_SYSV
583fd0c672fSmrg# define KERNEL_FILE "/unix"
584fd0c672fSmrg# else
585fd0c672fSmrg# define KERNEL_FILE "/vmunix"
586fd0c672fSmrg# endif /* SYSTYPE_SYSV */
587fd0c672fSmrg#endif /* umips */
588fd0c672fSmrg
589fd0c672fSmrg#ifdef sequent
590fd0c672fSmrg#define KERNEL_FILE "/dynix"
591fd0c672fSmrg#endif /* sequent */
592fd0c672fSmrg
593fd0c672fSmrg#ifdef hcx
594fd0c672fSmrg#define KERNEL_FILE "/unix"
595fd0c672fSmrg#endif /* hcx */
596fd0c672fSmrg
597fd0c672fSmrg#ifdef MOTOROLA
598fd0c672fSmrg#if defined(SYSV) && defined(m68k)
599fd0c672fSmrg#define KERNEL_FILE "/sysV68"
600fd0c672fSmrg#endif
601fd0c672fSmrg#if defined(SYSV) && defined(m88k)
602fd0c672fSmrg#define KERNEL_FILE "/unix"
603fd0c672fSmrg#endif
604fd0c672fSmrg#ifdef SVR4
605fd0c672fSmrg#define KERNEL_FILE "/unix"
606fd0c672fSmrg#endif
607fd0c672fSmrg#endif /* MOTOROLA */
608fd0c672fSmrg
609fd0c672fSmrg#ifdef sgi
610fd0c672fSmrg#if (OSMAJORVERSION > 4)
611fd0c672fSmrg#define KERNEL_FILE "/unix"
612fd0c672fSmrg#endif
613fd0c672fSmrg#endif
614fd0c672fSmrg
615fd0c672fSmrg/*
616fd0c672fSmrg * provide default for everyone else
617fd0c672fSmrg */
618fd0c672fSmrg#ifndef KERNEL_FILE
619fd0c672fSmrg#ifdef SVR4
620fd0c672fSmrg#define KERNEL_FILE "/stand/unix"
621fd0c672fSmrg#else
622fd0c672fSmrg#ifdef SYSV
623fd0c672fSmrg#define KERNEL_FILE "/unix"
624fd0c672fSmrg#else
625fd0c672fSmrg/* If a BSD system, check in <paths.h> */
626fd0c672fSmrg#   ifdef BSD
627fd0c672fSmrg#    include <paths.h>
628fd0c672fSmrg#    ifdef _PATH_UNIX
629fd0c672fSmrg#     define KERNEL_FILE _PATH_UNIX
630fd0c672fSmrg#    else
631fd0c672fSmrg#     ifdef _PATH_KERNEL
632fd0c672fSmrg#      define KERNEL_FILE _PATH_KERNEL
633fd0c672fSmrg#     else
634fd0c672fSmrg#      define KERNEL_FILE "/vmunix"
635fd0c672fSmrg#     endif
636fd0c672fSmrg#    endif
637fd0c672fSmrg#   else /* BSD */
638fd0c672fSmrg#    define KERNEL_FILE "/vmunix"
639fd0c672fSmrg#   endif /* BSD */
640fd0c672fSmrg#endif /* SYSV */
641fd0c672fSmrg#endif /* SVR4 */
642fd0c672fSmrg#endif /* KERNEL_FILE */
643fd0c672fSmrg#endif /* KERNEL_FILE */
644fd0c672fSmrg
645fd0c672fSmrg
646fd0c672fSmrg#ifndef KERNEL_LOAD_VARIABLE
647fd0c672fSmrg#    if defined(BSD) && (BSD >= 199103)
648fd0c672fSmrg#        define KERNEL_LOAD_VARIABLE "_averunnable"
649fd0c672fSmrg#    endif /* BSD >= 199103 */
650fd0c672fSmrg
651fd0c672fSmrg#    ifdef alliant
652fd0c672fSmrg#        define KERNEL_LOAD_VARIABLE "_Loadavg"
653fd0c672fSmrg#    endif /* alliant */
654fd0c672fSmrg
655fd0c672fSmrg#    ifdef CRAY
656fd0c672fSmrg#        if defined(CRAY2) && OSMAJORVERSION == 4
657fd0c672fSmrg#            define KERNEL_LOAD_VARIABLE "avenrun"
658fd0c672fSmrg#        else
659fd0c672fSmrg#            define KERNEL_LOAD_VARIABLE "sysinfo"
660fd0c672fSmrg#            define SYSINFO
661fd0c672fSmrg#        endif /* defined(CRAY2) && OSMAJORVERSION == 4 */
662fd0c672fSmrg#    endif /* CRAY */
663fd0c672fSmrg
664fd0c672fSmrg#    ifdef hpux
665fd0c672fSmrg#        ifdef __hp9000s800
666fd0c672fSmrg#            define KERNEL_LOAD_VARIABLE "avenrun"
667fd0c672fSmrg#        endif /* hp9000s800 */
668fd0c672fSmrg#    endif /* hpux */
669fd0c672fSmrg
670fd0c672fSmrg#    ifdef umips
671fd0c672fSmrg#        ifdef SYSTYPE_SYSV
672fd0c672fSmrg#            define KERNEL_LOAD_VARIABLE "avenrun"
673fd0c672fSmrg#        else
674fd0c672fSmrg#            define KERNEL_LOAD_VARIABLE "_avenrun"
675fd0c672fSmrg#        endif /* SYSTYPE_SYSV */
676fd0c672fSmrg#    endif /* umips */
677fd0c672fSmrg
678fd0c672fSmrg#    ifdef sgi
679fd0c672fSmrg#	 define KERNEL_LOAD_VARIABLE "avenrun"
680fd0c672fSmrg#    endif /* sgi */
681fd0c672fSmrg
682fd0c672fSmrg#    ifdef AIXV3
683fd0c672fSmrg#        define KERNEL_LOAD_VARIABLE "sysinfo"
684fd0c672fSmrg#    endif /* AIXV3 */
685fd0c672fSmrg
686fd0c672fSmrg#    ifdef MOTOROLA
687fd0c672fSmrg#        if defined(SYSV) && defined(m68k)
688fd0c672fSmrg#            define KERNEL_LOAD_VARIABLE "sysinfo"
689fd0c672fSmrg#        endif
690fd0c672fSmrg#        if defined(SYSV) && defined(m88k)
691fd0c672fSmrg#            define KERNEL_LOAD_VARIABLE "_sysinfo"
692fd0c672fSmrg#        endif
693fd0c672fSmrg#        ifdef SVR4
694fd0c672fSmrg#            define KERNEL_LOAD_VARIABLE "avenrun"
695fd0c672fSmrg#        endif
696fd0c672fSmrg#    endif /* MOTOROLA */
697fd0c672fSmrg
698fd0c672fSmrg#endif /* KERNEL_LOAD_VARIABLE */
699fd0c672fSmrg
700fd0c672fSmrg/*
701fd0c672fSmrg * provide default for everyone else
702fd0c672fSmrg */
703fd0c672fSmrg
704fd0c672fSmrg#ifndef KERNEL_LOAD_VARIABLE
705fd0c672fSmrg#    ifdef USG
706fd0c672fSmrg#        define KERNEL_LOAD_VARIABLE "sysinfo"
707fd0c672fSmrg#        define SYSINFO
708fd0c672fSmrg#    else
709fd0c672fSmrg#    ifdef SVR4
710fd0c672fSmrg#        define KERNEL_LOAD_VARIABLE "avenrun"
711fd0c672fSmrg#    else
712fd0c672fSmrg#        define KERNEL_LOAD_VARIABLE "_avenrun"
713fd0c672fSmrg#    endif
714fd0c672fSmrg#    endif
715fd0c672fSmrg#endif /* KERNEL_LOAD_VARIABLE */
716fd0c672fSmrg
717fd0c672fSmrgstatic struct nlist namelist[] = {	    /* namelist for vmunix grubbing */
718fd0c672fSmrg#define LOADAV 0
719fd0c672fSmrg    {KERNEL_LOAD_VARIABLE},
720fd0c672fSmrg    {0}
721fd0c672fSmrg};
722fd0c672fSmrg
723fd0c672fSmrgstatic int kmem;
724fd0c672fSmrgstatic long loadavg_seek;
725fd0c672fSmrg
726fd0c672fSmrgvoid InitLoadPoint()
727fd0c672fSmrg{
72848e69166Smrg#if !defined(SVR4) && !defined(sgi) && !defined(MOTOROLA) && !defined(AIXV5) && !(BSD >= 199103) && !defined(__APPLE__)
729fd0c672fSmrg    extern void nlist();
730fd0c672fSmrg#endif
731fd0c672fSmrg
732fd0c672fSmrg#ifdef AIXV3
733fd0c672fSmrg    knlist( namelist, 1, sizeof(struct nlist));
734fd0c672fSmrg#else
735fd0c672fSmrg    nlist( KERNEL_FILE, namelist);
736fd0c672fSmrg#endif
737fd0c672fSmrg    /*
738fd0c672fSmrg     * Some systems appear to set only one of these to Zero if the entry could
739fd0c672fSmrg     * not be found, I hope no_one returns Zero as a good value, or bad things
740fd0c672fSmrg     * will happen to you.  (I have a hard time believing the value will
741fd0c672fSmrg     * ever really be zero anyway).   CDP 5/17/89.
742fd0c672fSmrg     */
743fd0c672fSmrg#ifdef hcx
744fd0c672fSmrg    if (namelist[LOADAV].n_type == 0 &&
745fd0c672fSmrg#else
746fd0c672fSmrg    if (namelist[LOADAV].n_type == 0 ||
747fd0c672fSmrg#endif /* hcx */
748fd0c672fSmrg	namelist[LOADAV].n_value == 0) {
749fd0c672fSmrg	xload_error("cannot get name list from", KERNEL_FILE);
750fd0c672fSmrg	exit(-1);
751fd0c672fSmrg    }
752fd0c672fSmrg    loadavg_seek = namelist[LOADAV].n_value;
753fd0c672fSmrg#if defined(umips) && defined(SYSTYPE_SYSV)
754fd0c672fSmrg    loadavg_seek &= 0x7fffffff;
755fd0c672fSmrg#endif /* umips && SYSTYPE_SYSV */
756fd0c672fSmrg#if (defined(CRAY) && defined(SYSINFO))
757fd0c672fSmrg    loadavg_seek += ((char *) (((struct sysinfo *)NULL)->avenrun)) -
758fd0c672fSmrg	((char *) NULL);
759fd0c672fSmrg#endif /* CRAY && SYSINFO */
760fd0c672fSmrg    kmem = open(KMEM_FILE, O_RDONLY);
761fd0c672fSmrg    if (kmem < 0) xload_error("cannot open", KMEM_FILE);
762fd0c672fSmrg}
763fd0c672fSmrg
764fd0c672fSmrg/* ARGSUSED */
765fd0c672fSmrgvoid GetLoadPoint( w, closure, call_data )
766fd0c672fSmrg     Widget	w;		/* unused */
767fd0c672fSmrg     XtPointer	closure;	/* unused */
768fd0c672fSmrg     XtPointer	call_data;	/* pointer to (double) return value */
769fd0c672fSmrg{
770fd0c672fSmrg  	double *loadavg = (double *)call_data;
771fd0c672fSmrg
772fd0c672fSmrg	(void) lseek(kmem, loadavg_seek, 0);
773fd0c672fSmrg
774a8bb11d0Smrg#if defined (UTEK) || defined(sequent) || defined(alliant) || defined(SVR4) || defined(sgi) || defined(hcx) || (BSD >= 199103)
775fd0c672fSmrg	{
776fd0c672fSmrg		long temp;
777fd0c672fSmrg		(void) read(kmem, (char *)&temp, sizeof(long));
778fd0c672fSmrg		*loadavg = (double)temp/FSCALE;
779fd0c672fSmrg	}
780a8bb11d0Smrg#else /* else not UTEK or sequent or alliant or SVR4 or sgi or hcx */
781fd0c672fSmrg#  if defined(umips) || (defined(ultrix) && defined(mips))
782fd0c672fSmrg	{
783fd0c672fSmrg		fix temp;
784fd0c672fSmrg		(void) read(kmem, (char *)&temp, sizeof(fix));
785fd0c672fSmrg		*loadavg = FIX_TO_DBL(temp);
786fd0c672fSmrg	}
787fd0c672fSmrg#  else /* not umips or ultrix risc */
788fd0c672fSmrg#    ifdef AIXV3
789fd0c672fSmrg        {
790fd0c672fSmrg          struct sysinfo sysinfo_now;
791fd0c672fSmrg          struct sysinfo sysinfo_last;
792fd0c672fSmrg          static firsttime = TRUE;
793fd0c672fSmrg          static double runavg = 0.0, swpavg = 0.0;
794fd0c672fSmrg
795fd0c672fSmrg          (void) lseek(kmem, loadavg_seek, 0);
796fd0c672fSmrg          (void) read(kmem, (char *)&sysinfo_last, sizeof(struct sysinfo));
797fd0c672fSmrg          if (firsttime)
798fd0c672fSmrg            {
799fd0c672fSmrg              *loadavg = 0.0;
800fd0c672fSmrg              firsttime = FALSE;
801fd0c672fSmrg            }
802fd0c672fSmrg          else
803fd0c672fSmrg            {
804fd0c672fSmrg              sleep(1);
805fd0c672fSmrg              (void) lseek(kmem, loadavg_seek, 0);
806fd0c672fSmrg              (void) read(kmem, (char *)&sysinfo_now, sizeof(struct sysinfo));
807fd0c672fSmrg              runavg *= 0.8; swpavg *= 0.8;
808fd0c672fSmrg              if (sysinfo_now.runocc != sysinfo_last.runocc)
809fd0c672fSmrg                runavg += 0.2*((sysinfo_now.runque - sysinfo_last.runque - 1)
810fd0c672fSmrg                          /(double)(sysinfo_now.runocc - sysinfo_last.runocc));
811fd0c672fSmrg              if (sysinfo_now.swpocc != sysinfo_last.swpocc)
812fd0c672fSmrg                swpavg += 0.2*((sysinfo_now.swpque - sysinfo_last.swpque)
813fd0c672fSmrg                          /(double)(sysinfo_now.swpocc - sysinfo_last.swpocc));
814fd0c672fSmrg              *loadavg = runavg + swpavg;
815fd0c672fSmrg              sysinfo_last = sysinfo_now;
816fd0c672fSmrg            }
817fd0c672fSmrg          /* otherwise we leave load alone. */
818fd0c672fSmrg        }
819fd0c672fSmrg#    else /* not AIXV3 */
820fd0c672fSmrg#      if defined(MOTOROLA) && defined(SYSV)
821fd0c672fSmrg	{
822fd0c672fSmrg        static int init = 0;
823fd0c672fSmrg        static kmem;
824fd0c672fSmrg        static long loadavg_seek;
825fd0c672fSmrg
826fd0c672fSmrg#define CEXP    0.25            /* Constant used for load averaging */
827fd0c672fSmrg
828fd0c672fSmrg        struct sysinfo sysinfod;
829fd0c672fSmrg        static double oldloadavg;
830fd0c672fSmrg        static double cexp = CEXP;
831fd0c672fSmrg        static long sv_rq, sv_oc;   /* save old values */
832fd0c672fSmrg        double rq, oc;              /* amount values have changed */
833fd0c672fSmrg
834fd0c672fSmrg        if (!init)
835fd0c672fSmrg        {
836fd0c672fSmrg            if (nlist(KERNEL_FILE,namelist) == -1)
837fd0c672fSmrg            {
838fd0c672fSmrg                perror("xload: nlist()");
839fd0c672fSmrg                xload_error("cannot get name list from", KERNEL_FILE);
840fd0c672fSmrg            }
841fd0c672fSmrg            loadavg_seek = namelist[0].n_value;
842fd0c672fSmrg
843fd0c672fSmrg            kmem = open(KMEM_FILE, O_RDONLY);
844fd0c672fSmrg            if (kmem < 0)
845fd0c672fSmrg            {
846fd0c672fSmrg                perror("xload: open()");
847fd0c672fSmrg                xload_error("cannot open", KMEM_FILE);
848fd0c672fSmrg            }
849fd0c672fSmrg        }
850fd0c672fSmrg
851fd0c672fSmrg        lseek(kmem, loadavg_seek, 0);
852fd0c672fSmrg        if (read(kmem, &sysinfod, (int) sizeof (struct sysinfo)) == -1)
853fd0c672fSmrg        {
854fd0c672fSmrg             perror("xload: read() SYSINFONL");
855fd0c672fSmrg             xload_error("read failed from", KMEM_FILE);
856fd0c672fSmrg        }
857fd0c672fSmrg
858fd0c672fSmrg        if (!init)
859fd0c672fSmrg        {
860fd0c672fSmrg            init = 1;
861fd0c672fSmrg            sv_rq = sysinfod.runque;
862fd0c672fSmrg            sv_oc = sysinfod.runocc;
863fd0c672fSmrg            oldloadavg = *loadavg = 0.0;
864fd0c672fSmrg            return;
865fd0c672fSmrg        }
866fd0c672fSmrg        /*
867fd0c672fSmrg         * calculate the amount the values have
868fd0c672fSmrg         * changed since last update
869fd0c672fSmrg         */
870fd0c672fSmrg        rq = (double) sysinfod.runque - sv_rq;
871fd0c672fSmrg        oc = (double) sysinfod.runocc - sv_oc;
872fd0c672fSmrg
873fd0c672fSmrg        /*
874fd0c672fSmrg         * save old values for next time
875fd0c672fSmrg         */
876fd0c672fSmrg        sv_rq = sysinfod.runque;
877fd0c672fSmrg        sv_oc = sysinfod.runocc;
878fd0c672fSmrg
879fd0c672fSmrg        if (oc == 0.0)          /* avoid divide by zero  */
880fd0c672fSmrg        {
881fd0c672fSmrg                *loadavg = (1.0 - cexp) * oldloadavg;
882fd0c672fSmrg
883fd0c672fSmrg        }
884fd0c672fSmrg        else
885fd0c672fSmrg        {
886fd0c672fSmrg                *loadavg = ((1.0 - cexp) * oldloadavg) + ((rq / oc) * cexp);
887fd0c672fSmrg        }
888fd0c672fSmrg        oldloadavg = *loadavg;
889fd0c672fSmrg	}
890fd0c672fSmrg#      else /* not MOTOROLA */
891fd0c672fSmrg#     if defined(sony) && OSMAJORVERSION == 4
892fd0c672fSmrg#      ifdef mips
893fd0c672fSmrg	{
894fd0c672fSmrg		fix temp;
895fd0c672fSmrg		(void) read(kmem, (char *)&temp, sizeof(fix));
896fd0c672fSmrg		*loadavg = FIX_TO_DBL(temp);
897fd0c672fSmrg	}
898fd0c672fSmrg#      else /* not mips */
899fd0c672fSmrg	{
900fd0c672fSmrg		long temp;
901fd0c672fSmrg		(void) read(kmem, (char *)&temp, sizeof(long));
902fd0c672fSmrg		*loadavg = (double)temp/FSCALE;
903fd0c672fSmrg	}
904fd0c672fSmrg#      endif /* mips */
905fd0c672fSmrg#     else /* not sony NEWSOS4 */
906fd0c672fSmrg	(void) read(kmem, (char *)loadavg, sizeof(double));
907fd0c672fSmrg#      endif /* sony NEWOS4 */
908fd0c672fSmrg#     endif /* MOTOROLA else */
909fd0c672fSmrg#    endif /* AIXV3 else */
910fd0c672fSmrg#  endif /* umips else */
911a8bb11d0Smrg#endif /* SVR4 or ... else */
912fd0c672fSmrg	return;
913fd0c672fSmrg}
914a8bb11d0Smrg#endif /* HAVE_GETLOADAVG else */
915fd0c672fSmrg#endif /* __bsdi__ else */
916fd0c672fSmrg#endif /* __QNXNTO__ else */
917fd0c672fSmrg#endif /* __osf__ else */
918fd0c672fSmrg#endif /* LOADSTUB else */
91948e69166Smrg#endif /* __APPLE__ else */
920fd0c672fSmrg#endif /* __GNU__ else */
921fd0c672fSmrg#endif /* linux else */
922fd0c672fSmrg#endif /* SYSV && i386 else */
923fd0c672fSmrg
924a8bb11d0Smrgstatic void xload_error(const char *str1, const char *str2)
925fd0c672fSmrg{
926fd0c672fSmrg    (void) fprintf(stderr,"xload: %s %s\n", str1, str2);
927fd0c672fSmrg#ifdef __bsdi__
928fd0c672fSmrg    if (kd)
929fd0c672fSmrg	kvm_close(kd);
930fd0c672fSmrg#endif
931fd0c672fSmrg    exit(-1);
932fd0c672fSmrg}
933fd0c672fSmrg
934fd0c672fSmrg#endif /* END of __CYGWIN__ */
935