get_load.c revision fd0c672f
1/* $XdotOrg: xc/programs/xload/get_load.c,v 1.2 2004/04/23 19:54:57 eich Exp $ */ 2/* $XConsortium: get_load.c /main/37 1996/03/09 09:38:04 kaleb $ */ 3/* $XFree86: xc/programs/xload/get_load.c,v 1.21tsi Exp $ */ 4/* 5 6Copyright (c) 1989 X Consortium 7 8Permission is hereby granted, free of charge, to any person obtaining 9a copy of this software and associated documentation files (the 10"Software"), to deal in the Software without restriction, including 11without limitation the rights to use, copy, modify, merge, publish, 12distribute, sublicense, and/or sell copies of the Software, and to 13permit persons to whom the Software is furnished to do so, subject to 14the following conditions: 15 16The above copyright notice and this permission notice shall be included 17in all copies or substantial portions of the Software. 18 19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR 23OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 24ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25OTHER DEALINGS IN THE SOFTWARE. 26 27Except as contained in this notice, the name of the X Consortium shall 28not be used in advertising or otherwise to promote the sale, use or 29other dealings in this Software without prior written authorization 30from the X Consortium. 31 32*/ 33 34/* 35 * get_load - get system load 36 * 37 * Authors: Many and varied... 38 * 39 * Call InitLoadPoint() to initialize. 40 * GetLoadPoint() is a callback for the StripChart widget. 41 */ 42 43#ifdef HAVE_CONFIG_H 44# include "config.h" 45#endif 46 47#include <X11/Xos.h> 48#include <X11/Intrinsic.h> 49#include <X11/Xlocale.h> 50#include <stdio.h> 51#include <stdlib.h> 52#include "xload.h" 53 54#if defined(__CYGWIN__) 55#include <windows.h> 56typedef struct { 57 DWORD stat; 58 union { 59 LONG vLong; 60 double vDouble; 61 LONGLONG vLongLong; 62 void *string; 63 } u; 64} COUNTER; 65static HANDLE query; 66static HANDLE counter; 67static HINSTANCE hdll; 68static long (__stdcall *pdhopen)(LPCSTR, DWORD, HANDLE); 69static long (__stdcall *pdhaddcounter)(HANDLE, LPCSTR, DWORD, HANDLE*); 70static long (__stdcall *pdhcollectquerydata)(HANDLE); 71static long (__stdcall *pdhgetformattedcountervalue)(HANDLE, DWORD, LPDWORD, COUNTER*); 72#define CYGWIN_PERF 73void InitLoadPoint() 74{ 75 long ret; 76 hdll=LoadLibrary("pdh.dll"); 77 if (!hdll) exit(-1); 78 pdhopen=(void*)GetProcAddress(hdll, "PdhOpenQueryA"); 79 if (!pdhopen) exit(-1); 80 pdhaddcounter=(void*)GetProcAddress(hdll, "PdhAddCounterA"); 81 if (!pdhaddcounter) exit(-1); 82 pdhcollectquerydata=(void*)GetProcAddress(hdll, "PdhCollectQueryData"); 83 if (!pdhcollectquerydata) exit(-1); 84 pdhgetformattedcountervalue=(void*)GetProcAddress(hdll, "PdhGetFormattedCounterValue"); 85 if (!pdhgetformattedcountervalue) exit(-1); 86 ret = pdhopen( NULL , 0, &query ); 87 if (ret!=0) exit(-1); 88 ret = pdhaddcounter(query, "\\Processor(_Total)\\% Processor Time", 0, &counter); 89 if (ret!=0) exit(-1); 90} 91void GetLoadPoint( w, closure, call_data ) /* SYSV386 version */ 92 Widget w; /* unused */ 93 XtPointer closure; /* unused */ 94 XtPointer call_data; /* pointer to (double) return value */ 95{ 96 double *loadavg = (double *)call_data; 97 COUNTER fmtvalue; 98 long ret; 99 *loadavg = 0.0; 100 ret = pdhcollectquerydata(query); 101 if (ret!=0) return; 102 ret = pdhgetformattedcountervalue(counter, 0x200, NULL, &fmtvalue); 103 if (ret!=0) return; 104 *loadavg = (fmtvalue.u.vDouble-0.01)/100.0; 105} 106#else 107 108 109#if !defined(DGUX) 110#if defined(att) || defined(QNX4) 111#define LOADSTUB 112#endif 113 114#ifndef macII 115#ifndef apollo 116#ifndef LOADSTUB 117#if !defined(linux) && !defined(__UNIXOS2__) && !defined(__GLIBC__) 118#include <nlist.h> 119#endif /* !linux && ... */ 120#endif /* LOADSTUB */ 121#endif /* apollo */ 122#endif /* macII */ 123 124#if defined(MOTOROLA) && defined(SYSV) 125#include <sys/sysinfo.h> 126#endif 127 128#ifdef sun 129# include <sys/param.h> 130# if !defined(HAVE_CONFIG_H) && defined(SVR4) 131# define HAVE_LIBKSTAT 1 132# endif 133# ifdef HAVE_LIBKSTAT 134# include <kstat.h> 135# include <errno.h> 136# elif defined(i386) && !defined(SVR4) 137# include <kvm.h> 138# define KVM_ROUTINES 139# endif /* i386 */ 140#endif 141 142#ifdef CSRG_BASED 143#include <sys/param.h> 144#endif 145 146#if defined(umips) || (defined(ultrix) && defined(mips)) 147#include <sys/fixpoint.h> 148#endif 149 150#if defined(CRAY) || defined(AIXV3) 151#include <sys/param.h> 152#define word word_t 153#include <sys/sysinfo.h> 154#undef word 155#undef n_type 156#define n_type n_value 157#endif /* CRAY */ 158 159#ifdef sequent 160#include <sys/vm.h> 161#endif /* sequent */ 162 163#ifdef macII 164#include <a.out.h> 165#include <sys/var.h> 166#define X_AVENRUN 0 167#define fxtod(i) (vec[i].high+(vec[i].low/65536.0)) 168struct lavnum { 169 unsigned short high; 170 unsigned short low; 171}; 172#endif /* macII */ 173 174#ifdef hcx 175#include <sys/param.h> 176#endif /* hcx */ 177 178#if defined(UTEK) || defined(alliant) || (defined(MOTOROLA) && defined(SVR4)) 179#define FSCALE 100.0 180#endif 181 182#ifdef sequent 183#define FSCALE 1000.0 184#endif 185 186#ifdef sgi 187#define FSCALE 1024.0 188#endif 189 190#if defined(sony) && OSMAJORVERSION == 4 191#ifdef mips 192#include <sys/fixpoint.h> 193#else 194#include <sys/param.h> 195#endif 196#endif 197 198#ifdef __osf__ 199/* 200 * Use the table(2) interface; it doesn't require setuid root. 201 * 202 * Select 0, 1, or 2 for 5, 30, or 60 second load averages. 203 */ 204#ifndef WHICH_AVG 205#define WHICH_AVG 1 206#endif 207#include <sys/table.h> 208#endif 209 210#ifdef SVR4 211#ifndef FSCALE 212#define FSCALE (1 << 8) 213#endif 214#endif 215 216#ifdef X_NOT_POSIX 217extern long lseek(); 218#endif 219 220void xload_error(char *, char *); 221 222 223#ifdef apollo 224#include <apollo/base.h> 225#include <apollo/time.h> 226typedef struct { 227 short state; /* ready, waiting, etc. */ 228 pinteger usr; /* user sr */ 229 linteger upc; /* user pc */ 230 linteger usp; /* user stack pointer */ 231 linteger usb; /* user sb ptr (A6) */ 232 time_$clock_t cpu_total; /* cumulative cpu used by process */ 233 unsigned short priority; /* process priority */ 234 } proc1_$info_t; 235 236void proc1_$get_cput( 237 time_$clock_t *cput 238); 239 240void proc1_$get_info( 241 short &pid, 242 proc1_$info_t *info, 243 status_$t *sts 244); 245 246static int lastNullCpu; 247static int lastClock; 248 249void InitLoadPoint() /* Apollo version */ 250{ 251 time_$clock_t timeNow; 252 proc1_$info_t info; 253 status_$t st; 254 255 proc1_$get_info( (short) 2, &info, &st ); 256 time_$clock( &timeNow ); 257 258 lastClock = timeNow.low32; 259 lastNullCpu = info.cpu_total.low32; 260} 261 262/* ARGSUSED */ 263void GetLoadPoint( w, closure, call_data ) /* Apollo version */ 264 Widget w; /* unused */ 265 XtPointer closure; /* unused */ 266 XtPointer call_data; /* pointer to (double) return value */ 267{ 268 time_$clock_t timeNow; 269 double temp; 270 proc1_$info_t info; 271 status_$t st; 272 273 proc1_$get_info( (short) 2, &info, &st ); 274 time_$clock( &timeNow ); 275 276 temp = info.cpu_total.low32 - lastNullCpu; 277 *(double *)call_data = 1.0 - temp / (timeNow.low32 - lastClock); 278 279 lastClock = timeNow.low32; 280 lastNullCpu = info.cpu_total.low32; 281} 282#else /* not apollo */ 283#if defined(SYSV) && defined(i386) 284/* 285 * inspired by 'avgload' by John F. Haugh II 286 */ 287#include <sys/param.h> 288#include <sys/buf.h> 289#include <sys/immu.h> 290#include <sys/region.h> 291#include <sys/var.h> 292#include <sys/proc.h> 293#define KERNEL_FILE "/unix" 294#define KMEM_FILE "/dev/kmem" 295#define VAR_NAME "v" 296#define PROC_NAME "proc" 297#define BUF_NAME "buf" 298#define DECAY 0.8 299struct nlist namelist[] = { 300 {VAR_NAME}, 301 {PROC_NAME}, 302 {BUF_NAME}, 303 {0}, 304}; 305 306static int kmem; 307static struct var v; 308static struct proc *p; 309static XtPointer first_buf, last_buf; 310 311void InitLoadPoint() /* SYSV386 version */ 312{ 313 int i; 314 315 nlist( KERNEL_FILE, namelist); 316 317 for (i=0; namelist[i].n_name; i++) 318 if (namelist[i].n_value == 0) 319 xload_error("cannot get name list from", KERNEL_FILE); 320 321 if ((kmem = open(KMEM_FILE, O_RDONLY)) < 0) 322 xload_error("cannot open", KMEM_FILE); 323 324 if (lseek(kmem, namelist[0].n_value, 0) == -1) 325 xload_error("cannot seek", VAR_NAME); 326 327 if (read(kmem, &v, sizeof(v)) != sizeof(v)) 328 xload_error("cannot read", VAR_NAME); 329 330 if ((p=(struct proc *)malloc(v.v_proc*sizeof(*p))) == NULL) 331 xload_error("cannot allocat space for", PROC_NAME); 332 333 first_buf = (XtPointer) namelist[2].n_value; 334 last_buf = (char *)first_buf + v.v_buf * sizeof(struct buf); 335} 336 337/* ARGSUSED */ 338void GetLoadPoint( w, closure, call_data ) /* SYSV386 version */ 339Widget w; /* unused */ 340XtPointer closure; /* unused */ 341XtPointer call_data; /* pointer to (double) return value */ 342{ 343 double *loadavg = (double *)call_data; 344 static double avenrun = 0.0; 345 int i, nproc, size; 346 347 (void) lseek(kmem, namelist[0].n_value, 0); 348 (void) read(kmem, &v, sizeof(v)); 349 350 size = (struct proc *)v.ve_proc - (struct proc *)namelist[1].n_value; 351 352 (void) lseek(kmem, namelist[1].n_value, 0); 353 (void) read(kmem, p, size * sizeof(struct proc)); 354 355 for (nproc = 0, i=0; i<size; i++) 356 if ((p[i].p_stat == SRUN) || 357 (p[i].p_stat == SIDL) || 358 (p[i].p_stat == SXBRK) || 359 (p[i].p_stat == SSLEEP && (p[i].p_pri < PZERO) && 360 (p[i].p_wchan >= (char *)first_buf) && (p[i].p_wchan < (char *)last_buf))) 361 nproc++; 362 363 /* update the load average using a decay filter */ 364 avenrun = DECAY * avenrun + nproc * (1.0 - DECAY); 365 *loadavg = avenrun; 366 367 return; 368} 369#else /* not (SYSV && i386) */ 370#ifdef KVM_ROUTINES 371/* 372 * Sun 386i Code - abstracted to see the wood for the trees 373 */ 374 375static struct nlist nl[2]; 376static kvm_t *kd; 377 378void 379InitLoadPoint() /* Sun 386i version */ 380{ 381 kd = kvm_open("/vmunix", NULL, NULL, O_RDONLY, "Load Widget"); 382 if (kd == (kvm_t *)0) { 383 xload_error("cannot get access to kernel address space", ""); 384 } 385 386 nl[0].n_name = "avenrun"; 387 nl[1].n_name = NULL; 388 389 if (kvm_nlist(kd, nl) != 0) { 390 xload_error("cannot get name list", ""); 391 } 392 393 if (nl[0].n_value == 0) { 394 xload_error("Cannot find address for avenrun in the kernel\n", ""); 395 } 396} 397 398/* ARGSUSED */ 399void 400GetLoadPoint( w, closure, call_data ) /* Sun 386i version */ 401Widget w; /* unused */ 402XtPointer closure; /* unused */ 403XtPointer call_data; /* pointer to (double) return value */ 404{ 405 double *loadavg = (double *)call_data; 406 long temp; 407 408 if (kvm_read(kd, nl[0].n_value, (char *)&temp, sizeof (temp)) != 409 sizeof (temp)) { 410 xload_error("Kernel read error", ""); 411 } 412 *loadavg = (double)temp/FSCALE; 413} 414#else /* not KVM_ROUTINES */ 415 416#if defined(linux) || (defined(__FreeBSD_kernel__) && defined(__GLIBC__)) 417 418void InitLoadPoint() 419{ 420 return; 421} 422 423void GetLoadPoint( w, closure, call_data ) 424 Widget w; /* unused */ 425 XtPointer closure; /* unused */ 426 XtPointer call_data; /* pointer to (double) return value */ 427{ 428 static int fd = -1; 429 int n; 430 char buf[10] = {0, }; 431#ifndef X_LOCALE 432 char *dp; 433 static char ldp = 0; 434#endif 435 436 437 if (fd < 0) 438 { 439 if (fd == -2 || 440 (fd = open("/proc/loadavg", O_RDONLY)) < 0) 441 { 442 fd = -2; 443 *(double *)call_data = 0.0; 444 return; 445 } 446#ifndef X_LOCALE 447 ldp = *localeconv()->decimal_point; 448#endif 449 } 450 else 451 lseek(fd, 0, 0); 452 453 if ((n = read(fd, buf, sizeof(buf)-1)) > 0) { 454#ifndef X_LOCALE 455 if (ldp != '.') 456 while ((dp = memchr(buf,'.',sizeof(buf)-1)) != NULL) { 457 *(char *)dp = ldp; 458 } 459 460#endif 461 if (sscanf(buf, "%lf", (double *)call_data) == 1) 462 return; 463 } 464 465 466 *(double *)call_data = 0.0; /* temporary hiccup */ 467 468 return; 469} 470 471#else /* linux */ 472 473#ifdef __GNU__ 474 475#include <mach.h> 476 477static processor_set_t default_set; 478 479void InitLoadPoint() 480{ 481 if (processor_set_default (mach_host_self (), &default_set) != KERN_SUCCESS) 482 xload_error("cannot get processor_set_default", ""); 483} 484 485/* ARGSUSED */ 486void GetLoadPoint( w, closure, call_data ) 487 Widget w; /* unused */ 488 XtPointer closure; /* unused */ 489 XtPointer call_data; /* pointer to (double) return value */ 490{ 491 host_t host; 492 struct processor_set_basic_info info; 493 unsigned info_count; 494 495 info_count = PROCESSOR_SET_BASIC_INFO_COUNT; 496 if (processor_set_info (default_set, PROCESSOR_SET_BASIC_INFO, &host, 497 (processor_set_info_t) &info, &info_count) 498 != KERN_SUCCESS) 499 { 500 InitLoadPoint(); 501 info.load_average = 0; 502 } 503 504 *(double *)call_data = info.load_average * 1000 / LOAD_SCALE; 505 506 return; 507} 508 509#else /* __GNU__ */ 510 511#ifdef __DARWIN__ 512 513#include <mach/mach.h> 514 515static mach_port_t host_priv_port; 516 517void InitLoadPoint() 518{ 519 host_priv_port = mach_host_self(); 520} 521 522/* ARGSUSED */ 523void GetLoadPoint( w, closure, call_data ) 524 Widget w; /* unused */ 525 XtPointer closure; /* unused */ 526 XtPointer call_data; /* pointer to (double) return value */ 527{ 528 double *loadavg = (double *)call_data; 529 530 struct host_load_info load_data; 531 int host_count; 532 kern_return_t kr; 533 534 host_count = sizeof(load_data)/sizeof(integer_t); 535 kr = host_statistics(host_priv_port, HOST_LOAD_INFO, 536 (host_info_t)&load_data, &host_count); 537 if (kr != KERN_SUCCESS) 538 xload_error("cannot get host statistics", ""); 539 *loadavg = (double)load_data.avenrun[0]/LOAD_SCALE; 540 return; 541} 542 543#else /* __DARWIN__ */ 544 545#ifdef LOADSTUB 546 547void InitLoadPoint() 548{ 549} 550 551/* ARGSUSED */ 552void GetLoadPoint( w, closure, call_data ) 553 Widget w; /* unused */ 554 XtPointer closure; /* unused */ 555 XtPointer call_data; /* pointer to (double) return value */ 556{ 557 *(double *)call_data = 1.0; 558} 559 560#else /* not LOADSTUB */ 561 562#ifdef __osf__ 563 564void InitLoadPoint() 565{ 566} 567 568/*ARGSUSED*/ 569void GetLoadPoint( w, closure, call_data ) 570 Widget w; /* unused */ 571 XtPointer closure; /* unused */ 572 XtPointer call_data; /* pointer to (double) return value */ 573{ 574 double *loadavg = (double *)call_data; 575 struct tbl_loadavg load_data; 576 577 if (table(TBL_LOADAVG, 0, (char *)&load_data, 1, sizeof(load_data)) < 0) 578 xload_error("error reading load average", ""); 579 *loadavg = (load_data.tl_lscale == 0) ? 580 load_data.tl_avenrun.d[WHICH_AVG] : 581 load_data.tl_avenrun.l[WHICH_AVG] / (double)load_data.tl_lscale; 582} 583 584#else /* not __osf__ */ 585 586#ifdef __QNXNTO__ 587#include <time.h> 588#include <sys/neutrino.h> 589static _Uint64t nto_idle = 0, nto_idle_last = 0; 590static int nto_idle_id; 591static struct timespec nto_now, nto_last; 592 593void 594InitLoadPoint() 595{ 596 nto_idle_id = ClockId(1, 1); /* Idle thread */ 597 ClockTime(nto_idle_id, NULL, &nto_idle_last); 598 clock_gettime( CLOCK_REALTIME, &nto_last); 599} 600 601/* ARGSUSED */ 602void 603GetLoadPoint( w, closure, call_data ) /* QNX NTO version */ 604Widget w; /* unused */ 605XtPointer closure; /* unused */ 606XtPointer call_data; /* pointer to (double) return value */ 607{ 608 double *loadavg = (double *)call_data; 609 double timediff; 610 double temp = 0.0; 611 612 ClockTime(nto_idle_id, NULL, &nto_idle); 613 clock_gettime( CLOCK_REALTIME, &nto_now); 614 timediff = 1000000000.0 * (nto_now.tv_sec - nto_last.tv_sec) 615 + (nto_now.tv_nsec - nto_last.tv_nsec); 616 temp = 1.0 - (nto_idle-nto_idle_last)/timediff; 617 *loadavg = temp >= 0 ? temp : 0; 618 nto_idle_last = nto_idle; 619 nto_last = nto_now; 620} 621#else /* not __QNXNTO__ */ 622 623#ifdef __bsdi__ 624#include <kvm.h> 625 626static struct nlist nl[] = { 627 { "_averunnable" }, 628#define X_AVERUNNABLE 0 629 { "_fscale" }, 630#define X_FSCALE 1 631 { "" }, 632}; 633static kvm_t *kd; 634static int fscale; 635 636void InitLoadPoint() 637{ 638 fixpt_t averunnable[3]; /* unused really */ 639 640 if ((kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, NULL)) == NULL) 641 xload_error("can't open kvm files", ""); 642 643 if (kvm_nlist(kd, nl) != 0) 644 xload_error("can't read name list", ""); 645 646 if (kvm_read(kd, (off_t)nl[X_AVERUNNABLE].n_value, (char *)averunnable, 647 sizeof(averunnable)) != sizeof(averunnable)) 648 xload_error("couldn't obtain _averunnable variable", ""); 649 650 if (kvm_read(kd, (off_t)nl[X_FSCALE].n_value, (char *)&fscale, 651 sizeof(fscale)) != sizeof(fscale)) 652 xload_error("couldn't obtain _fscale variable", ""); 653 654 return; 655} 656 657void GetLoadPoint(w, closure, call_data) 658 Widget w; /* unused */ 659 XtPointer closure; /* unused */ 660 XtPointer call_data; /* ptr to (double) return value */ 661{ 662 double *loadavg = (double *)call_data; 663 fixpt_t t; 664 665 if (kvm_read(kd, (off_t)nl[X_AVERUNNABLE].n_value, (char *)&t, 666 sizeof(t)) != sizeof(t)) 667 xload_error("couldn't obtain load average", ""); 668 669 *loadavg = (double)t/fscale; 670 671 return; 672} 673 674#else /* not __bsdi__ */ 675#if defined(BSD) && (BSD >= 199306) 676#include <stdlib.h> 677 678void InitLoadPoint() 679{ 680} 681 682void GetLoadPoint(w, closure, call_data) 683 Widget w; /* unused */ 684 XtPointer closure; /* unused */ 685 XtPointer call_data; /* ptr to (double) return value */ 686{ 687 double *loadavg = (double *)call_data; 688 689 if (getloadavg(loadavg, 1) < 0) 690 xload_error("couldn't obtain load average", ""); 691} 692 693#else /* not BSD >= 199306 */ 694#if defined(sun) && defined(HAVE_LIBKSTAT) 695 696static kstat_t *ksp; 697static kstat_ctl_t *kc; 698 699void 700InitLoadPoint(void) 701{ 702 if ((kc = kstat_open()) == NULL) 703 xload_error("kstat_open failed:", strerror(errno)); 704 705 if ((ksp = kstat_lookup(kc, "unix", 0, "system_misc")) == NULL) 706 xload_error("kstat_lookup failed:", strerror(errno)); 707} 708 709void 710GetLoadPoint(Widget w, XtPointer closure, XtPointer call_data) 711{ 712 kstat_named_t *vp; 713 double *loadavg = (double *)call_data; 714 715 if (kstat_read(kc, ksp, NULL) == -1) 716 xload_error("kstat_read failed:", strerror(errno)); 717 718 if ((vp = kstat_data_lookup(ksp, "avenrun_1min")) == NULL) 719 xload_error("kstat_data_lookup failed:", strerror(errno)); 720 721 *loadavg = (double)vp->value.l / FSCALE; 722} 723#else /* not Solaris */ 724 725#ifndef KMEM_FILE 726#define KMEM_FILE "/dev/kmem" 727#endif 728 729#ifndef KERNEL_FILE 730 731#ifdef alliant 732#define KERNEL_FILE "/vmunix" 733#endif /* alliant */ 734 735#ifdef CRAY 736#define KERNEL_FILE "/unicos" 737#endif /* CRAY */ 738 739#ifdef hpux 740#define KERNEL_FILE "/hp-ux" 741#endif /* hpux */ 742 743#ifdef macII 744#define KERNEL_FILE "/unix" 745#endif /* macII */ 746 747#ifdef umips 748# ifdef SYSTYPE_SYSV 749# define KERNEL_FILE "/unix" 750# else 751# define KERNEL_FILE "/vmunix" 752# endif /* SYSTYPE_SYSV */ 753#endif /* umips */ 754 755#ifdef sequent 756#define KERNEL_FILE "/dynix" 757#endif /* sequent */ 758 759#ifdef hcx 760#define KERNEL_FILE "/unix" 761#endif /* hcx */ 762 763#ifdef MOTOROLA 764#if defined(SYSV) && defined(m68k) 765#define KERNEL_FILE "/sysV68" 766#endif 767#if defined(SYSV) && defined(m88k) 768#define KERNEL_FILE "/unix" 769#endif 770#ifdef SVR4 771#define KERNEL_FILE "/unix" 772#endif 773#endif /* MOTOROLA */ 774 775#if defined(sun) && defined(SVR4) 776#define KERNEL_FILE "/kernel/unix" 777#endif 778 779#ifdef sgi 780#if (OSMAJORVERSION > 4) 781#define KERNEL_FILE "/unix" 782#endif 783#endif 784 785/* 786 * provide default for everyone else 787 */ 788#ifndef KERNEL_FILE 789#ifdef SVR4 790#define KERNEL_FILE "/stand/unix" 791#else 792#ifdef SYSV 793#define KERNEL_FILE "/unix" 794#else 795/* If a BSD system, check in <paths.h> */ 796# ifdef BSD 797# include <paths.h> 798# ifdef _PATH_UNIX 799# define KERNEL_FILE _PATH_UNIX 800# else 801# ifdef _PATH_KERNEL 802# define KERNEL_FILE _PATH_KERNEL 803# else 804# define KERNEL_FILE "/vmunix" 805# endif 806# endif 807# else /* BSD */ 808# define KERNEL_FILE "/vmunix" 809# endif /* BSD */ 810#endif /* SYSV */ 811#endif /* SVR4 */ 812#endif /* KERNEL_FILE */ 813#endif /* KERNEL_FILE */ 814 815 816#ifndef KERNEL_LOAD_VARIABLE 817# if defined(BSD) && (BSD >= 199103) 818# define KERNEL_LOAD_VARIABLE "_averunnable" 819# endif /* BSD >= 199103 */ 820 821# ifdef alliant 822# define KERNEL_LOAD_VARIABLE "_Loadavg" 823# endif /* alliant */ 824 825# ifdef CRAY 826# if defined(CRAY2) && OSMAJORVERSION == 4 827# define KERNEL_LOAD_VARIABLE "avenrun" 828# else 829# define KERNEL_LOAD_VARIABLE "sysinfo" 830# define SYSINFO 831# endif /* defined(CRAY2) && OSMAJORVERSION == 4 */ 832# endif /* CRAY */ 833 834# ifdef hpux 835# ifdef __hp9000s800 836# define KERNEL_LOAD_VARIABLE "avenrun" 837# endif /* hp9000s800 */ 838# endif /* hpux */ 839 840# ifdef umips 841# ifdef SYSTYPE_SYSV 842# define KERNEL_LOAD_VARIABLE "avenrun" 843# else 844# define KERNEL_LOAD_VARIABLE "_avenrun" 845# endif /* SYSTYPE_SYSV */ 846# endif /* umips */ 847 848# ifdef sgi 849# define KERNEL_LOAD_VARIABLE "avenrun" 850# endif /* sgi */ 851 852# ifdef AIXV3 853# define KERNEL_LOAD_VARIABLE "sysinfo" 854# endif /* AIXV3 */ 855 856# ifdef MOTOROLA 857# if defined(SYSV) && defined(m68k) 858# define KERNEL_LOAD_VARIABLE "sysinfo" 859# endif 860# if defined(SYSV) && defined(m88k) 861# define KERNEL_LOAD_VARIABLE "_sysinfo" 862# endif 863# ifdef SVR4 864# define KERNEL_LOAD_VARIABLE "avenrun" 865# endif 866# endif /* MOTOROLA */ 867 868#endif /* KERNEL_LOAD_VARIABLE */ 869 870/* 871 * provide default for everyone else 872 */ 873 874#ifndef KERNEL_LOAD_VARIABLE 875# ifdef USG 876# define KERNEL_LOAD_VARIABLE "sysinfo" 877# define SYSINFO 878# else 879# ifdef SVR4 880# define KERNEL_LOAD_VARIABLE "avenrun" 881# else 882# define KERNEL_LOAD_VARIABLE "_avenrun" 883# endif 884# endif 885#endif /* KERNEL_LOAD_VARIABLE */ 886 887#ifdef macII 888static struct var v; 889static int pad[2]; /* This padding is needed if xload compiled on */ 890 /* a/ux 1.1 is executed on a/ux 1.0, because */ 891 /* the var structure had too much padding in 1.0, */ 892 /* so the 1.0 kernel writes past the end of the 1.1 */ 893 /* var structure in the uvar() call. */ 894static struct nlist nl[2]; 895static struct lavnum vec[3]; 896#else /* not macII */ 897static struct nlist namelist[] = { /* namelist for vmunix grubbing */ 898#define LOADAV 0 899 {KERNEL_LOAD_VARIABLE}, 900 {0} 901}; 902#endif /* macII */ 903 904static int kmem; 905static long loadavg_seek; 906 907void InitLoadPoint() 908{ 909#ifdef macII 910 extern nlist(); 911 912 int i; 913 914 strcpy(nl[0].n_name, "avenrun"); 915 nl[1].n_name[0] = '\0'; 916 917 kmem = open(KMEM_FILE, O_RDONLY); 918 if (kmem < 0) { 919 xload_error("cannot open", KMEM_FILE); 920 } 921 922 uvar(&v); 923 924 if (nlist( KERNEL_FILE, nl) != 0) { 925 xload_error("cannot get name list from", KERNEL_FILE); 926 } 927 for (i = 0; i < 2; i++) { 928 nl[i].n_value = (int)nl[i].n_value - v.v_kvoffset; 929 } 930#else /* not macII */ 931#if !defined(SVR4) && !defined(sgi) && !defined(MOTOROLA) && !defined(AIXV5) && !(BSD >= 199103) 932 extern void nlist(); 933#endif 934 935#ifdef AIXV3 936 knlist( namelist, 1, sizeof(struct nlist)); 937#else 938 nlist( KERNEL_FILE, namelist); 939#endif 940 /* 941 * Some systems appear to set only one of these to Zero if the entry could 942 * not be found, I hope no_one returns Zero as a good value, or bad things 943 * will happen to you. (I have a hard time believing the value will 944 * ever really be zero anyway). CDP 5/17/89. 945 */ 946#ifdef hcx 947 if (namelist[LOADAV].n_type == 0 && 948#else 949 if (namelist[LOADAV].n_type == 0 || 950#endif /* hcx */ 951 namelist[LOADAV].n_value == 0) { 952 xload_error("cannot get name list from", KERNEL_FILE); 953 exit(-1); 954 } 955 loadavg_seek = namelist[LOADAV].n_value; 956#if defined(umips) && defined(SYSTYPE_SYSV) 957 loadavg_seek &= 0x7fffffff; 958#endif /* umips && SYSTYPE_SYSV */ 959#if (defined(CRAY) && defined(SYSINFO)) 960 loadavg_seek += ((char *) (((struct sysinfo *)NULL)->avenrun)) - 961 ((char *) NULL); 962#endif /* CRAY && SYSINFO */ 963 kmem = open(KMEM_FILE, O_RDONLY); 964 if (kmem < 0) xload_error("cannot open", KMEM_FILE); 965#endif /* macII else */ 966} 967 968/* ARGSUSED */ 969void GetLoadPoint( w, closure, call_data ) 970 Widget w; /* unused */ 971 XtPointer closure; /* unused */ 972 XtPointer call_data; /* pointer to (double) return value */ 973{ 974 double *loadavg = (double *)call_data; 975 976#ifdef macII 977 lseek(kmem, (long)nl[X_AVENRUN].n_value, 0); 978#else 979 (void) lseek(kmem, loadavg_seek, 0); 980#endif 981 982#if defined(sun) || defined (UTEK) || defined(sequent) || defined(alliant) || defined(SVR4) || defined(sgi) || defined(hcx) || (BSD >= 199103) 983 { 984 long temp; 985 (void) read(kmem, (char *)&temp, sizeof(long)); 986 *loadavg = (double)temp/FSCALE; 987 } 988#else /* else not sun or UTEK or sequent or alliant or SVR4 or sgi or hcx */ 989# ifdef macII 990 { 991 read(kmem, vec, 3*sizeof(struct lavnum)); 992 *loadavg = fxtod(0); 993 } 994# else /* else not macII */ 995# if defined(umips) || (defined(ultrix) && defined(mips)) 996 { 997 fix temp; 998 (void) read(kmem, (char *)&temp, sizeof(fix)); 999 *loadavg = FIX_TO_DBL(temp); 1000 } 1001# else /* not umips or ultrix risc */ 1002# ifdef AIXV3 1003 { 1004 struct sysinfo sysinfo_now; 1005 struct sysinfo sysinfo_last; 1006 static firsttime = TRUE; 1007 static double runavg = 0.0, swpavg = 0.0; 1008 1009 (void) lseek(kmem, loadavg_seek, 0); 1010 (void) read(kmem, (char *)&sysinfo_last, sizeof(struct sysinfo)); 1011 if (firsttime) 1012 { 1013 *loadavg = 0.0; 1014 firsttime = FALSE; 1015 } 1016 else 1017 { 1018 sleep(1); 1019 (void) lseek(kmem, loadavg_seek, 0); 1020 (void) read(kmem, (char *)&sysinfo_now, sizeof(struct sysinfo)); 1021 runavg *= 0.8; swpavg *= 0.8; 1022 if (sysinfo_now.runocc != sysinfo_last.runocc) 1023 runavg += 0.2*((sysinfo_now.runque - sysinfo_last.runque - 1) 1024 /(double)(sysinfo_now.runocc - sysinfo_last.runocc)); 1025 if (sysinfo_now.swpocc != sysinfo_last.swpocc) 1026 swpavg += 0.2*((sysinfo_now.swpque - sysinfo_last.swpque) 1027 /(double)(sysinfo_now.swpocc - sysinfo_last.swpocc)); 1028 *loadavg = runavg + swpavg; 1029 sysinfo_last = sysinfo_now; 1030 } 1031 /* otherwise we leave load alone. */ 1032 } 1033# else /* not AIXV3 */ 1034# if defined(MOTOROLA) && defined(SYSV) 1035 { 1036 static int init = 0; 1037 static kmem; 1038 static long loadavg_seek; 1039 1040#define CEXP 0.25 /* Constant used for load averaging */ 1041 1042 struct sysinfo sysinfod; 1043 static double oldloadavg; 1044 static double cexp = CEXP; 1045 static long sv_rq, sv_oc; /* save old values */ 1046 double rq, oc; /* amount values have changed */ 1047 1048 if (!init) 1049 { 1050 if (nlist(KERNEL_FILE,namelist) == -1) 1051 { 1052 perror("xload: nlist()"); 1053 xload_error("cannot get name list from", KERNEL_FILE); 1054 } 1055 loadavg_seek = namelist[0].n_value; 1056 1057 kmem = open(KMEM_FILE, O_RDONLY); 1058 if (kmem < 0) 1059 { 1060 perror("xload: open()"); 1061 xload_error("cannot open", KMEM_FILE); 1062 } 1063 } 1064 1065 lseek(kmem, loadavg_seek, 0); 1066 if (read(kmem, &sysinfod, (int) sizeof (struct sysinfo)) == -1) 1067 { 1068 perror("xload: read() SYSINFONL"); 1069 xload_error("read failed from", KMEM_FILE); 1070 } 1071 1072 if (!init) 1073 { 1074 init = 1; 1075 sv_rq = sysinfod.runque; 1076 sv_oc = sysinfod.runocc; 1077 oldloadavg = *loadavg = 0.0; 1078 return; 1079 } 1080 /* 1081 * calculate the amount the values have 1082 * changed since last update 1083 */ 1084 rq = (double) sysinfod.runque - sv_rq; 1085 oc = (double) sysinfod.runocc - sv_oc; 1086 1087 /* 1088 * save old values for next time 1089 */ 1090 sv_rq = sysinfod.runque; 1091 sv_oc = sysinfod.runocc; 1092 1093 if (oc == 0.0) /* avoid divide by zero */ 1094 { 1095 *loadavg = (1.0 - cexp) * oldloadavg; 1096 1097 } 1098 else 1099 { 1100 *loadavg = ((1.0 - cexp) * oldloadavg) + ((rq / oc) * cexp); 1101 } 1102 oldloadavg = *loadavg; 1103 } 1104# else /* not MOTOROLA */ 1105# if defined(sony) && OSMAJORVERSION == 4 1106# ifdef mips 1107 { 1108 fix temp; 1109 (void) read(kmem, (char *)&temp, sizeof(fix)); 1110 *loadavg = FIX_TO_DBL(temp); 1111 } 1112# else /* not mips */ 1113 { 1114 long temp; 1115 (void) read(kmem, (char *)&temp, sizeof(long)); 1116 *loadavg = (double)temp/FSCALE; 1117 } 1118# endif /* mips */ 1119# else /* not sony NEWSOS4 */ 1120 (void) read(kmem, (char *)loadavg, sizeof(double)); 1121# endif /* sony NEWOS4 */ 1122# endif /* MOTOROLA else */ 1123# endif /* AIXV3 else */ 1124# endif /* umips else */ 1125# endif /* macII else */ 1126#endif /* sun or SVR4 or ... else */ 1127 return; 1128} 1129#endif /* sun else */ 1130#endif /* BSD >= 199306 else */ 1131#endif /* __bsdi__ else */ 1132#endif /* __QNXNTO__ else */ 1133#endif /* __osf__ else */ 1134#endif /* LOADSTUB else */ 1135#endif /* __DARWIN__ else */ 1136#endif /* __GNU__ else */ 1137#endif /* linux else */ 1138#endif /* KVM_ROUTINES else */ 1139#endif /* SYSV && i386 else */ 1140 1141void xload_error(str1, str2) 1142char *str1, *str2; 1143{ 1144 (void) fprintf(stderr,"xload: %s %s\n", str1, str2); 1145#ifdef __bsdi__ 1146 if (kd) 1147 kvm_close(kd); 1148#endif 1149 exit(-1); 1150} 1151 1152#endif /* apollo else */ 1153 1154#else /* !DGUX */ 1155 1156/* INTEL DGUX Release 4.20MU04 1157 * Copyright 1999 Takis Psarogiannakopoulos 1158 * Cambridge, UK 1159 * <takis@dpmms.cam.ac.uk> 1160 */ 1161 1162#include <errno.h> 1163#include <nlist.h> 1164#include <sys/dg_sys_info.h> 1165 1166static struct dg_sys_info_load_info load_info; /* DG/ux */ 1167 1168#define KERNEL_FILE "/dgux" 1169#define LDAV_SYMBOL "_avenrun" 1170 1171void InitLoadPoint() 1172{ 1173 1174} 1175 1176void GetLoadPoint(w, closure, call_data) 1177 Widget w; /* unused */ 1178 XtPointer closure; /* unused */ 1179 XtPointer call_data; /* ptr to (double) return value */ 1180{ 1181 double *loadavg = (double *)call_data; 1182 1183 if (getloadavg(loadavg, 1) < 0) 1184 xload_error("couldn't obtain load average", ""); 1185} 1186 1187xload_error(str1, str2) 1188char *str1, *str2; 1189{ 1190 (void) fprintf(stderr,"xload: %s %s\n", str1, str2); 1191 exit(-1); 1192} 1193 1194#if !defined (LDAV_CVT) && defined (FSCALE) 1195#define LDAV_CVT(n) (((double) (n)) / FSCALE) 1196#endif 1197#if !defined(LDAV_CVT) && defined(LOAD_AVE_CVT) 1198#define LDAV_CVT(n) (LOAD_AVE_CVT (n) / 100.0) 1199#endif 1200#define LOAD_AVE_TYPE double 1201#ifndef LDAV_CVT 1202#define LDAV_CVT(n) ((double) (n)) 1203#endif /* !LDAV_CVT */ 1204static int channel; 1205static int getloadavg_initialized; 1206static long offset; 1207static struct nlist nl[2]; 1208 1209 1210/* GETLOADAVG FUNCTION FOR DG/ux R4.20MU04 */ 1211 1212int 1213getloadavg (double loadavg[], int nelem) 1214{ 1215 int elem = 0; /* Return value. */ 1216 int result =0 ; 1217 1218 /* This call can return -1 for an error, but with good args 1219 it's not supposed to fail. The first argument is for no 1220 apparent reason of type `long int *'. */ 1221 result = dg_sys_info ((long int *) &load_info, 1222 DG_SYS_INFO_LOAD_INFO_TYPE, DG_SYS_INFO_LOAD_VERSION_0); 1223 if ( result == -1) 1224 { 1225 return(-1); 1226 } 1227 if (nelem > 0) 1228 loadavg[elem++] = load_info.one_minute; 1229 if (nelem > 1) 1230 loadavg[elem++] = load_info.five_minute; 1231 if (nelem > 2) 1232 loadavg[elem++] = load_info.fifteen_minute; 1233 1234 return elem; 1235} 1236 1237#endif /* END OF DG/ux */ 1238 1239 1240#endif /* END of __CYGWIN__ */ 1241