get_load.c revision 953c684b
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__) 52953c684bSmrg# define WIN32_LEAN_AND_MEAN 53953c684bSmrg# 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*); 70953c684bSmrg# 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); 87953c684bSmrg 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} 104953c684bSmrg#else /* not CYGWIN */ 105fd0c672fSmrg 106953c684bSmrgstatic void xload_error(const char *, const char *) _X_NORETURN; 107fd0c672fSmrg 108953c684bSmrg# ifdef HAVE_GETLOADAVG 109953c684bSmrg# include <stdlib.h> 110953c684bSmrg# ifdef HAVE_SYS_LOADAVG_H 111953c684bSmrg# include <sys/loadavg.h> /* Solaris definition of getloadavg */ 112953c684bSmrg# endif 113fd0c672fSmrg 114953c684bSmrgvoid InitLoadPoint(void) 115953c684bSmrg{ 116953c684bSmrg} 117fd0c672fSmrg 118953c684bSmrgvoid GetLoadPoint( 119953c684bSmrg Widget w, /* unused */ 120953c684bSmrg XtPointer closure, /* unused */ 121953c684bSmrg XtPointer call_data) /* ptr to (double) return value */ 122953c684bSmrg{ 123953c684bSmrg double *loadavg = (double *)call_data; 124fd0c672fSmrg 125953c684bSmrg if (getloadavg(loadavg, 1) < 0) 126953c684bSmrg xload_error("couldn't obtain load average", ""); 127953c684bSmrg} 128fd0c672fSmrg 129953c684bSmrg# else /* not HAVE_GETLOADAVG */ 130fd0c672fSmrg 131953c684bSmrg# if defined(att) || defined(QNX4) 132953c684bSmrg# define LOADSTUB 133953c684bSmrg# endif 134fd0c672fSmrg 135953c684bSmrg# ifndef LOADSTUB 136953c684bSmrg# if !defined(linux) && !defined(__GLIBC__) 137953c684bSmrg# include <nlist.h> 138953c684bSmrg# endif /* !linux && ... */ 139953c684bSmrg# endif /* LOADSTUB */ 140fd0c672fSmrg 141953c684bSmrg# ifdef CSRG_BASED 142953c684bSmrg# include <sys/param.h> 143953c684bSmrg# endif 144fd0c672fSmrg 145953c684bSmrg# ifdef sgi 146953c684bSmrg# define FSCALE 1024.0 147953c684bSmrg# endif 148fd0c672fSmrg 149953c684bSmrg# ifdef __osf__ 150fd0c672fSmrg/* 151fd0c672fSmrg * Use the table(2) interface; it doesn't require setuid root. 152fd0c672fSmrg * 153fd0c672fSmrg * Select 0, 1, or 2 for 5, 30, or 60 second load averages. 154fd0c672fSmrg */ 155953c684bSmrg# ifndef WHICH_AVG 156953c684bSmrg# define WHICH_AVG 1 157953c684bSmrg# endif 158953c684bSmrg# include <sys/table.h> 159953c684bSmrg# endif 160953c684bSmrg 161953c684bSmrg# ifdef SVR4 162953c684bSmrg# ifndef FSCALE 163953c684bSmrg# define FSCALE (1 << 8) 164953c684bSmrg# endif 165953c684bSmrg# endif 166953c684bSmrg 167953c684bSmrg# if defined(SYSV) && defined(i386) 168fd0c672fSmrg/* 169fd0c672fSmrg * inspired by 'avgload' by John F. Haugh II 170fd0c672fSmrg */ 171953c684bSmrg# include <sys/param.h> 172953c684bSmrg# include <sys/buf.h> 173953c684bSmrg# include <sys/immu.h> 174953c684bSmrg# include <sys/region.h> 175953c684bSmrg# include <sys/var.h> 176953c684bSmrg# include <sys/proc.h> 177953c684bSmrg# define KERNEL_FILE "/unix" 178953c684bSmrg# define KMEM_FILE "/dev/kmem" 179953c684bSmrg# define VAR_NAME "v" 180953c684bSmrg# define PROC_NAME "proc" 181953c684bSmrg# define BUF_NAME "buf" 182953c684bSmrg# define DECAY 0.8 183fd0c672fSmrgstruct nlist namelist[] = { 184fd0c672fSmrg {VAR_NAME}, 185fd0c672fSmrg {PROC_NAME}, 186fd0c672fSmrg {BUF_NAME}, 187fd0c672fSmrg {0}, 188fd0c672fSmrg}; 189fd0c672fSmrg 190fd0c672fSmrgstatic int kmem; 191fd0c672fSmrgstatic struct var v; 192fd0c672fSmrgstatic struct proc *p; 193fd0c672fSmrgstatic XtPointer first_buf, last_buf; 194fd0c672fSmrg 195fd0c672fSmrgvoid InitLoadPoint() /* SYSV386 version */ 196fd0c672fSmrg{ 197fd0c672fSmrg int i; 198fd0c672fSmrg 199fd0c672fSmrg nlist( KERNEL_FILE, namelist); 200fd0c672fSmrg 201953c684bSmrg for (i=0; namelist[i].n_name; i++) 202fd0c672fSmrg if (namelist[i].n_value == 0) 203fd0c672fSmrg xload_error("cannot get name list from", KERNEL_FILE); 204fd0c672fSmrg 205fd0c672fSmrg if ((kmem = open(KMEM_FILE, O_RDONLY)) < 0) 206fd0c672fSmrg xload_error("cannot open", KMEM_FILE); 207fd0c672fSmrg 208fd0c672fSmrg if (lseek(kmem, namelist[0].n_value, 0) == -1) 209fd0c672fSmrg xload_error("cannot seek", VAR_NAME); 210fd0c672fSmrg 211fd0c672fSmrg if (read(kmem, &v, sizeof(v)) != sizeof(v)) 212fd0c672fSmrg xload_error("cannot read", VAR_NAME); 213fd0c672fSmrg 214fd0c672fSmrg if ((p=(struct proc *)malloc(v.v_proc*sizeof(*p))) == NULL) 215fd0c672fSmrg xload_error("cannot allocat space for", PROC_NAME); 216953c684bSmrg 217fd0c672fSmrg first_buf = (XtPointer) namelist[2].n_value; 218fd0c672fSmrg last_buf = (char *)first_buf + v.v_buf * sizeof(struct buf); 219fd0c672fSmrg} 220953c684bSmrg 221fd0c672fSmrg/* ARGSUSED */ 222fd0c672fSmrgvoid GetLoadPoint( w, closure, call_data ) /* SYSV386 version */ 223fd0c672fSmrgWidget w; /* unused */ 224fd0c672fSmrgXtPointer closure; /* unused */ 225fd0c672fSmrgXtPointer call_data; /* pointer to (double) return value */ 226fd0c672fSmrg{ 227fd0c672fSmrg double *loadavg = (double *)call_data; 228fd0c672fSmrg static double avenrun = 0.0; 229fd0c672fSmrg int i, nproc, size; 230953c684bSmrg 231fd0c672fSmrg (void) lseek(kmem, namelist[0].n_value, 0); 232fd0c672fSmrg (void) read(kmem, &v, sizeof(v)); 233fd0c672fSmrg 234fd0c672fSmrg size = (struct proc *)v.ve_proc - (struct proc *)namelist[1].n_value; 235fd0c672fSmrg 236fd0c672fSmrg (void) lseek(kmem, namelist[1].n_value, 0); 237fd0c672fSmrg (void) read(kmem, p, size * sizeof(struct proc)); 238fd0c672fSmrg 239953c684bSmrg for (nproc = 0, i=0; i<size; i++) 240fd0c672fSmrg if ((p[i].p_stat == SRUN) || 241fd0c672fSmrg (p[i].p_stat == SIDL) || 242fd0c672fSmrg (p[i].p_stat == SXBRK) || 243fd0c672fSmrg (p[i].p_stat == SSLEEP && (p[i].p_pri < PZERO) && 244fd0c672fSmrg (p[i].p_wchan >= (char *)first_buf) && (p[i].p_wchan < (char *)last_buf))) 245fd0c672fSmrg nproc++; 246fd0c672fSmrg 247fd0c672fSmrg /* update the load average using a decay filter */ 248fd0c672fSmrg avenrun = DECAY * avenrun + nproc * (1.0 - DECAY); 249fd0c672fSmrg *loadavg = avenrun; 250fd0c672fSmrg 251fd0c672fSmrg return; 252fd0c672fSmrg} 253953c684bSmrg# else /* not (SYSV && i386) */ 254fd0c672fSmrg 255953c684bSmrg# if defined(linux) || (defined(__FreeBSD_kernel__) && defined(__GLIBC__)) 256fd0c672fSmrg 25748e69166Smrgvoid InitLoadPoint(void) 258fd0c672fSmrg{ 259fd0c672fSmrg return; 260fd0c672fSmrg} 261fd0c672fSmrg 26248e69166Smrgvoid GetLoadPoint( 26348e69166Smrg Widget w, /* unused */ 26448e69166Smrg XtPointer closure, /* unused */ 26548e69166Smrg XtPointer call_data) /* pointer to (double) return value */ 266fd0c672fSmrg{ 267fd0c672fSmrg static int fd = -1; 268fd0c672fSmrg int n; 269fd0c672fSmrg char buf[10] = {0, }; 270953c684bSmrg# ifndef X_LOCALE 271fd0c672fSmrg char *dp; 272fd0c672fSmrg static char ldp = 0; 273953c684bSmrg# endif 274fd0c672fSmrg 275fd0c672fSmrg 276fd0c672fSmrg if (fd < 0) 277fd0c672fSmrg { 278fd0c672fSmrg if (fd == -2 || 279fd0c672fSmrg (fd = open("/proc/loadavg", O_RDONLY)) < 0) 280fd0c672fSmrg { 281fd0c672fSmrg fd = -2; 282fd0c672fSmrg *(double *)call_data = 0.0; 283fd0c672fSmrg return; 284fd0c672fSmrg } 285953c684bSmrg# ifndef X_LOCALE 286fd0c672fSmrg ldp = *localeconv()->decimal_point; 287953c684bSmrg# endif 288fd0c672fSmrg } 289fd0c672fSmrg else 290fd0c672fSmrg lseek(fd, 0, 0); 291fd0c672fSmrg 292fd0c672fSmrg if ((n = read(fd, buf, sizeof(buf)-1)) > 0) { 293953c684bSmrg# ifndef X_LOCALE 294fd0c672fSmrg if (ldp != '.') 295fd0c672fSmrg while ((dp = memchr(buf,'.',sizeof(buf)-1)) != NULL) { 296fd0c672fSmrg *(char *)dp = ldp; 297fd0c672fSmrg } 298953c684bSmrg 299953c684bSmrg# endif 300fd0c672fSmrg if (sscanf(buf, "%lf", (double *)call_data) == 1) 301fd0c672fSmrg return; 302fd0c672fSmrg } 303953c684bSmrg 304fd0c672fSmrg 305fd0c672fSmrg *(double *)call_data = 0.0; /* temporary hiccup */ 306fd0c672fSmrg 307fd0c672fSmrg return; 308fd0c672fSmrg} 309fd0c672fSmrg 310953c684bSmrg# else /* linux */ 311fd0c672fSmrg 312953c684bSmrg# ifdef __GNU__ 313fd0c672fSmrg 314953c684bSmrg# include <mach.h> 315fd0c672fSmrg 316fd0c672fSmrgstatic processor_set_t default_set; 317fd0c672fSmrg 31848e69166Smrgvoid InitLoadPoint(void) 319fd0c672fSmrg{ 320fd0c672fSmrg if (processor_set_default (mach_host_self (), &default_set) != KERN_SUCCESS) 321fd0c672fSmrg xload_error("cannot get processor_set_default", ""); 322fd0c672fSmrg} 323fd0c672fSmrg 324fd0c672fSmrg/* ARGSUSED */ 32548e69166Smrgvoid GetLoadPoint( 32648e69166Smrg Widget w, /* unused */ 32748e69166Smrg XtPointer closure, /* unused */ 32848e69166Smrg XtPointer call_data) /* pointer to (double) return value */ 329fd0c672fSmrg{ 330fd0c672fSmrg host_t host; 331fd0c672fSmrg struct processor_set_basic_info info; 332fd0c672fSmrg unsigned info_count; 333fd0c672fSmrg 334fd0c672fSmrg info_count = PROCESSOR_SET_BASIC_INFO_COUNT; 335fd0c672fSmrg if (processor_set_info (default_set, PROCESSOR_SET_BASIC_INFO, &host, 336fd0c672fSmrg (processor_set_info_t) &info, &info_count) 337fd0c672fSmrg != KERN_SUCCESS) 338fd0c672fSmrg { 339fd0c672fSmrg InitLoadPoint(); 340fd0c672fSmrg info.load_average = 0; 341fd0c672fSmrg } 342fd0c672fSmrg 343fd0c672fSmrg *(double *)call_data = info.load_average * 1000 / LOAD_SCALE; 344fd0c672fSmrg 345fd0c672fSmrg return; 346fd0c672fSmrg} 347fd0c672fSmrg 348953c684bSmrg# else /* __GNU__ */ 349fd0c672fSmrg 350953c684bSmrg# ifdef __APPLE__ 351fd0c672fSmrg 352953c684bSmrg# include <mach/mach.h> 353fd0c672fSmrg 354fd0c672fSmrgstatic mach_port_t host_priv_port; 355fd0c672fSmrg 35648e69166Smrgvoid InitLoadPoint(void) 357fd0c672fSmrg{ 358fd0c672fSmrg host_priv_port = mach_host_self(); 359fd0c672fSmrg} 360fd0c672fSmrg 361fd0c672fSmrg/* ARGSUSED */ 36248e69166Smrgvoid GetLoadPoint( 36348e69166Smrg Widget w, /* unused */ 36448e69166Smrg XtPointer closure, /* unused */ 36548e69166Smrg XtPointer call_data) /* pointer to (double) return value */ 366fd0c672fSmrg{ 367fd0c672fSmrg double *loadavg = (double *)call_data; 368fd0c672fSmrg 369fd0c672fSmrg struct host_load_info load_data; 370fd0c672fSmrg int host_count; 371fd0c672fSmrg kern_return_t kr; 372fd0c672fSmrg 373fd0c672fSmrg host_count = sizeof(load_data)/sizeof(integer_t); 374fd0c672fSmrg kr = host_statistics(host_priv_port, HOST_LOAD_INFO, 375fd0c672fSmrg (host_info_t)&load_data, &host_count); 376fd0c672fSmrg if (kr != KERN_SUCCESS) 377fd0c672fSmrg xload_error("cannot get host statistics", ""); 378fd0c672fSmrg *loadavg = (double)load_data.avenrun[0]/LOAD_SCALE; 379fd0c672fSmrg return; 380fd0c672fSmrg} 381fd0c672fSmrg 382953c684bSmrg# else /* __APPLE__ */ 383fd0c672fSmrg 384953c684bSmrg# ifdef LOADSTUB 385fd0c672fSmrg 386fd0c672fSmrgvoid InitLoadPoint() 387fd0c672fSmrg{ 388fd0c672fSmrg} 389fd0c672fSmrg 390fd0c672fSmrg/* ARGSUSED */ 391fd0c672fSmrgvoid GetLoadPoint( w, closure, call_data ) 392fd0c672fSmrg Widget w; /* unused */ 393fd0c672fSmrg XtPointer closure; /* unused */ 394fd0c672fSmrg XtPointer call_data; /* pointer to (double) return value */ 395fd0c672fSmrg{ 396fd0c672fSmrg *(double *)call_data = 1.0; 397fd0c672fSmrg} 398fd0c672fSmrg 399953c684bSmrg# else /* not LOADSTUB */ 400fd0c672fSmrg 401953c684bSmrg# ifdef __osf__ 402fd0c672fSmrg 403fd0c672fSmrgvoid InitLoadPoint() 404fd0c672fSmrg{ 405fd0c672fSmrg} 406fd0c672fSmrg 407fd0c672fSmrg/*ARGSUSED*/ 408fd0c672fSmrgvoid GetLoadPoint( w, closure, call_data ) 409fd0c672fSmrg Widget w; /* unused */ 410fd0c672fSmrg XtPointer closure; /* unused */ 411fd0c672fSmrg XtPointer call_data; /* pointer to (double) return value */ 412fd0c672fSmrg{ 413fd0c672fSmrg double *loadavg = (double *)call_data; 414fd0c672fSmrg struct tbl_loadavg load_data; 415fd0c672fSmrg 416fd0c672fSmrg if (table(TBL_LOADAVG, 0, (char *)&load_data, 1, sizeof(load_data)) < 0) 417fd0c672fSmrg xload_error("error reading load average", ""); 418fd0c672fSmrg *loadavg = (load_data.tl_lscale == 0) ? 419fd0c672fSmrg load_data.tl_avenrun.d[WHICH_AVG] : 420fd0c672fSmrg load_data.tl_avenrun.l[WHICH_AVG] / (double)load_data.tl_lscale; 421fd0c672fSmrg} 422fd0c672fSmrg 423953c684bSmrg# else /* not __osf__ */ 424fd0c672fSmrg 425953c684bSmrg# ifdef __QNXNTO__ 426953c684bSmrg# include <time.h> 427953c684bSmrg# include <sys/neutrino.h> 428fd0c672fSmrgstatic _Uint64t nto_idle = 0, nto_idle_last = 0; 429fd0c672fSmrgstatic int nto_idle_id; 430fd0c672fSmrgstatic struct timespec nto_now, nto_last; 431fd0c672fSmrg 432fd0c672fSmrgvoid 43348e69166SmrgInitLoadPoint(void) 434fd0c672fSmrg{ 435fd0c672fSmrg nto_idle_id = ClockId(1, 1); /* Idle thread */ 436fd0c672fSmrg ClockTime(nto_idle_id, NULL, &nto_idle_last); 437fd0c672fSmrg clock_gettime( CLOCK_REALTIME, &nto_last); 438fd0c672fSmrg} 439fd0c672fSmrg 440fd0c672fSmrg/* ARGSUSED */ 441fd0c672fSmrgvoid 44248e69166SmrgGetLoadPoint( /* QNX NTO version */ 44348e69166Smrg Widget w, /* unused */ 44448e69166Smrg XtPointer closure, /* unused */ 44548e69166Smrg XtPointer call_data) /* pointer to (double) return value */ 446fd0c672fSmrg{ 447fd0c672fSmrg double *loadavg = (double *)call_data; 448fd0c672fSmrg double timediff; 449fd0c672fSmrg double temp = 0.0; 450fd0c672fSmrg 451fd0c672fSmrg ClockTime(nto_idle_id, NULL, &nto_idle); 452fd0c672fSmrg clock_gettime( CLOCK_REALTIME, &nto_now); 453fd0c672fSmrg timediff = 1000000000.0 * (nto_now.tv_sec - nto_last.tv_sec) 454fd0c672fSmrg + (nto_now.tv_nsec - nto_last.tv_nsec); 455fd0c672fSmrg temp = 1.0 - (nto_idle-nto_idle_last)/timediff; 456fd0c672fSmrg *loadavg = temp >= 0 ? temp : 0; 457fd0c672fSmrg nto_idle_last = nto_idle; 458fd0c672fSmrg nto_last = nto_now; 459fd0c672fSmrg} 460953c684bSmrg# else /* not __QNXNTO__ */ 461fd0c672fSmrg 462953c684bSmrg# ifdef __bsdi__ 463953c684bSmrg# include <kvm.h> 464fd0c672fSmrg 465fd0c672fSmrgstatic struct nlist nl[] = { 466fd0c672fSmrg { "_averunnable" }, 467953c684bSmrg# define X_AVERUNNABLE 0 468fd0c672fSmrg { "_fscale" }, 469953c684bSmrg# define X_FSCALE 1 470fd0c672fSmrg { "" }, 471fd0c672fSmrg}; 472fd0c672fSmrgstatic kvm_t *kd; 473fd0c672fSmrgstatic int fscale; 474fd0c672fSmrg 47548e69166Smrgvoid InitLoadPoint(void) 476fd0c672fSmrg{ 477fd0c672fSmrg fixpt_t averunnable[3]; /* unused really */ 478fd0c672fSmrg 479fd0c672fSmrg if ((kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, NULL)) == NULL) 480fd0c672fSmrg xload_error("can't open kvm files", ""); 481fd0c672fSmrg 482fd0c672fSmrg if (kvm_nlist(kd, nl) != 0) 483fd0c672fSmrg xload_error("can't read name list", ""); 484fd0c672fSmrg 485fd0c672fSmrg if (kvm_read(kd, (off_t)nl[X_AVERUNNABLE].n_value, (char *)averunnable, 486fd0c672fSmrg sizeof(averunnable)) != sizeof(averunnable)) 487fd0c672fSmrg xload_error("couldn't obtain _averunnable variable", ""); 488fd0c672fSmrg 489fd0c672fSmrg if (kvm_read(kd, (off_t)nl[X_FSCALE].n_value, (char *)&fscale, 490fd0c672fSmrg sizeof(fscale)) != sizeof(fscale)) 491fd0c672fSmrg xload_error("couldn't obtain _fscale variable", ""); 492fd0c672fSmrg 493fd0c672fSmrg return; 494fd0c672fSmrg} 495fd0c672fSmrg 49648e69166Smrgvoid GetLoadPoint( 49748e69166Smrg Widget w, /* unused */ 49848e69166Smrg XtPointer closure, /* unused */ 49948e69166Smrg XtPointer call_data) /* ptr to (double) return value */ 500fd0c672fSmrg{ 501fd0c672fSmrg double *loadavg = (double *)call_data; 502fd0c672fSmrg fixpt_t t; 503fd0c672fSmrg 504fd0c672fSmrg if (kvm_read(kd, (off_t)nl[X_AVERUNNABLE].n_value, (char *)&t, 505fd0c672fSmrg sizeof(t)) != sizeof(t)) 506fd0c672fSmrg xload_error("couldn't obtain load average", ""); 507fd0c672fSmrg 508fd0c672fSmrg *loadavg = (double)t/fscale; 509fd0c672fSmrg 510fd0c672fSmrg return; 511fd0c672fSmrg} 512fd0c672fSmrg 513953c684bSmrg# else /* not __bsdi__ */ 514953c684bSmrg# ifndef KMEM_FILE 515953c684bSmrg# define KMEM_FILE "/dev/kmem" 516953c684bSmrg# endif 517fd0c672fSmrg 518953c684bSmrg# ifndef KERNEL_FILE 519fd0c672fSmrg 520953c684bSmrg# ifdef hpux 521953c684bSmrg# define KERNEL_FILE "/hp-ux" 522953c684bSmrg# endif /* hpux */ 523fd0c672fSmrg 524953c684bSmrg# ifdef sgi 525953c684bSmrg# if (OSMAJORVERSION > 4) 526953c684bSmrg# define KERNEL_FILE "/unix" 527953c684bSmrg# endif 528953c684bSmrg# endif 529fd0c672fSmrg 530fd0c672fSmrg/* 531fd0c672fSmrg * provide default for everyone else 532fd0c672fSmrg */ 533953c684bSmrg# ifndef KERNEL_FILE 534953c684bSmrg# ifdef SVR4 535953c684bSmrg# define KERNEL_FILE "/stand/unix" 536953c684bSmrg# else 537953c684bSmrg# ifdef SYSV 538953c684bSmrg# define KERNEL_FILE "/unix" 539953c684bSmrg# else 540fd0c672fSmrg/* If a BSD system, check in <paths.h> */ 541953c684bSmrg# ifdef BSD 542953c684bSmrg# include <paths.h> 543953c684bSmrg# ifdef _PATH_UNIX 544953c684bSmrg# define KERNEL_FILE _PATH_UNIX 545953c684bSmrg# else 546953c684bSmrg# ifdef _PATH_KERNEL 547953c684bSmrg# define KERNEL_FILE _PATH_KERNEL 548953c684bSmrg# else 549953c684bSmrg# define KERNEL_FILE "/vmunix" 550953c684bSmrg# endif 551953c684bSmrg# endif 552953c684bSmrg# else /* BSD */ 553953c684bSmrg# define KERNEL_FILE "/vmunix" 554953c684bSmrg# endif /* BSD */ 555953c684bSmrg# endif /* SYSV */ 556953c684bSmrg# endif /* SVR4 */ 557953c684bSmrg# endif /* KERNEL_FILE */ 558953c684bSmrg# endif /* KERNEL_FILE */ 559953c684bSmrg 560953c684bSmrg 561953c684bSmrg# ifndef KERNEL_LOAD_VARIABLE 562953c684bSmrg# if defined(BSD) && (BSD >= 199103) 563953c684bSmrg# define KERNEL_LOAD_VARIABLE "_averunnable" 564953c684bSmrg# endif /* BSD >= 199103 */ 565953c684bSmrg 566953c684bSmrg# ifdef hpux 567953c684bSmrg# ifdef __hp9000s800 568953c684bSmrg# define KERNEL_LOAD_VARIABLE "avenrun" 569953c684bSmrg# endif /* hp9000s800 */ 570953c684bSmrg# endif /* hpux */ 571953c684bSmrg 572953c684bSmrg# ifdef sgi 573fd0c672fSmrg# define KERNEL_LOAD_VARIABLE "avenrun" 574953c684bSmrg# endif /* sgi */ 575fd0c672fSmrg 576953c684bSmrg# endif /* KERNEL_LOAD_VARIABLE */ 577fd0c672fSmrg 578fd0c672fSmrg/* 579fd0c672fSmrg * provide default for everyone else 580fd0c672fSmrg */ 581fd0c672fSmrg 582953c684bSmrg# ifndef KERNEL_LOAD_VARIABLE 583953c684bSmrg# ifdef USG 584953c684bSmrg# define KERNEL_LOAD_VARIABLE "sysinfo" 585953c684bSmrg# define SYSINFO 586953c684bSmrg# else 587953c684bSmrg# ifdef SVR4 588953c684bSmrg# define KERNEL_LOAD_VARIABLE "avenrun" 589953c684bSmrg# else 590953c684bSmrg# define KERNEL_LOAD_VARIABLE "_avenrun" 591953c684bSmrg# endif 592953c684bSmrg# endif 593953c684bSmrg# endif /* KERNEL_LOAD_VARIABLE */ 594fd0c672fSmrg 595fd0c672fSmrgstatic struct nlist namelist[] = { /* namelist for vmunix grubbing */ 596953c684bSmrg# define LOADAV 0 597fd0c672fSmrg {KERNEL_LOAD_VARIABLE}, 598fd0c672fSmrg {0} 599fd0c672fSmrg}; 600fd0c672fSmrg 601fd0c672fSmrgstatic int kmem; 602fd0c672fSmrgstatic long loadavg_seek; 603fd0c672fSmrg 604fd0c672fSmrgvoid InitLoadPoint() 605fd0c672fSmrg{ 606953c684bSmrg# if !defined(SVR4) && !defined(sgi) && !defined(AIXV5) && !(BSD >= 199103) && !defined(__APPLE__) 607fd0c672fSmrg extern void nlist(); 608953c684bSmrg# endif 609fd0c672fSmrg 610fd0c672fSmrg nlist( KERNEL_FILE, namelist); 611fd0c672fSmrg /* 612fd0c672fSmrg * Some systems appear to set only one of these to Zero if the entry could 613fd0c672fSmrg * not be found, I hope no_one returns Zero as a good value, or bad things 614fd0c672fSmrg * will happen to you. (I have a hard time believing the value will 615fd0c672fSmrg * ever really be zero anyway). CDP 5/17/89. 616fd0c672fSmrg */ 617fd0c672fSmrg if (namelist[LOADAV].n_type == 0 || 618fd0c672fSmrg namelist[LOADAV].n_value == 0) { 619fd0c672fSmrg xload_error("cannot get name list from", KERNEL_FILE); 620fd0c672fSmrg exit(-1); 621fd0c672fSmrg } 622fd0c672fSmrg loadavg_seek = namelist[LOADAV].n_value; 623fd0c672fSmrg kmem = open(KMEM_FILE, O_RDONLY); 624fd0c672fSmrg if (kmem < 0) xload_error("cannot open", KMEM_FILE); 625fd0c672fSmrg} 626fd0c672fSmrg 627fd0c672fSmrg/* ARGSUSED */ 628fd0c672fSmrgvoid GetLoadPoint( w, closure, call_data ) 629fd0c672fSmrg Widget w; /* unused */ 630fd0c672fSmrg XtPointer closure; /* unused */ 631fd0c672fSmrg XtPointer call_data; /* pointer to (double) return value */ 632fd0c672fSmrg{ 633fd0c672fSmrg double *loadavg = (double *)call_data; 634fd0c672fSmrg 635fd0c672fSmrg (void) lseek(kmem, loadavg_seek, 0); 636fd0c672fSmrg 637953c684bSmrg# if defined(SVR4) || defined(sgi) || (BSD >= 199103) 638fd0c672fSmrg { 639fd0c672fSmrg long temp; 640fd0c672fSmrg (void) read(kmem, (char *)&temp, sizeof(long)); 641fd0c672fSmrg *loadavg = (double)temp/FSCALE; 642fd0c672fSmrg } 643953c684bSmrg# else /* else not SVR4 or sgi or BSD */ 644fd0c672fSmrg (void) read(kmem, (char *)loadavg, sizeof(double)); 645953c684bSmrg# endif /* SVR4 or ... else */ 646fd0c672fSmrg return; 647fd0c672fSmrg} 648953c684bSmrg# endif /* __bsdi__ else */ 649953c684bSmrg# endif /* __QNXNTO__ else */ 650953c684bSmrg# endif /* __osf__ else */ 651953c684bSmrg# endif /* LOADSTUB else */ 652953c684bSmrg# endif /* __APPLE__ else */ 653953c684bSmrg# endif /* __GNU__ else */ 654953c684bSmrg# endif /* linux else */ 655953c684bSmrg# endif /* SYSV && i386 else */ 656953c684bSmrg# endif /* HAVE_GETLOADAVG else */ 657fd0c672fSmrg 658a8bb11d0Smrgstatic void xload_error(const char *str1, const char *str2) 659fd0c672fSmrg{ 660fd0c672fSmrg (void) fprintf(stderr,"xload: %s %s\n", str1, str2); 661953c684bSmrg# ifdef __bsdi__ 662fd0c672fSmrg if (kd) 663fd0c672fSmrg kvm_close(kd); 664953c684bSmrg# endif 665fd0c672fSmrg exit(-1); 666fd0c672fSmrg} 667fd0c672fSmrg 668fd0c672fSmrg#endif /* END of __CYGWIN__ */ 669