home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / A / PS / PROCPS-0.000 / PROCPS-0 / procps-0.97 / xproc / get_load.c next >
Encoding:
C/C++ Source or Header  |  1993-12-31  |  19.3 KB  |  803 lines

  1. /*
  2.  * get_load - get system load
  3.  *
  4.  * $XConsortium: get_load.c,v 1.26 91/07/25 14:20:25 rws Exp $
  5.  *
  6.  * Copyright 1989 Massachusetts Institute of Technology
  7.  *
  8.  * Permission to use, copy, modify, distribute, and sell this software and its
  9.  * documentation for any purpose is hereby granted without fee, provided that
  10.  * the above copyright notice appear in all copies and that both that
  11.  * copyright notice and this permission notice appear in supporting
  12.  * documentation, and that the name of M.I.T. not be used in advertising or
  13.  * publicity pertaining to distribution of the software without specific,
  14.  * written prior permission.  M.I.T. makes no representations about the
  15.  * suitability of this software for any purpose.  It is provided "as is"
  16.  * without express or implied warranty.
  17.  *
  18.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  19.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  20.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  21.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  22.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  23.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  24.  *
  25.  * Authors:  Many and varied...
  26.  *
  27.  * Call InitLoadPoint() to initialize.
  28.  * GetLoadPoint() is a callback for the StripChart widget.
  29.  */
  30.  
  31. #include <X11/Xos.h>
  32. #include <X11/Intrinsic.h>
  33. #include <stdio.h>
  34.  
  35. #ifdef att
  36. #define LOADSTUB
  37. #endif
  38.  
  39. #ifndef linux
  40. #ifndef macII
  41. #ifndef apollo
  42. #ifndef LOADSTUB
  43. #include <nlist.h>
  44. #endif /* LOADSTUB */
  45. #endif /* apollo */
  46. #endif /* macII */
  47. #endif /* linux */
  48.  
  49. #if defined(MOTOROLA) && defined(SYSV)
  50. #include <sys/sysinfo.h>
  51. #endif
  52.  
  53. #ifdef sun
  54. #    include <sys/param.h>
  55. #    ifdef i386
  56. #        include <kvm.h>
  57. #        define    KVM_ROUTINES
  58. #    endif /* i386 */
  59. #endif
  60.  
  61. #if defined(umips) || (defined(ultrix) && defined(mips))
  62. #include <sys/fixpoint.h>
  63. #endif
  64.  
  65. #if  defined(CRAY) || defined(AIXV3)
  66. #include <sys/param.h>
  67. #define word word_t
  68. #include <sys/sysinfo.h>
  69. #undef word
  70. #undef n_type
  71. #define n_type n_value
  72. #endif    /* CRAY */
  73.  
  74. #ifdef sequent
  75. #include <sys/vm.h>
  76. #endif /* sequent */
  77.  
  78. #ifdef macII
  79. #include <a.out.h>
  80. #include <sys/var.h>
  81. #define X_AVENRUN 0
  82. #define fxtod(i) (vec[i].high+(vec[i].low/65536.0))
  83. struct lavnum {
  84.     unsigned short high;
  85.     unsigned short low;
  86. };
  87. #endif /* macII */
  88.  
  89. #ifdef hcx
  90. #include <sys/param.h>
  91. #endif /* hcx */
  92.  
  93. #if defined(UTEK) || defined(alliant) || (defined(MOTOROLA) && defined(SVR4))
  94. #define FSCALE    100.0
  95. #endif
  96.  
  97. #ifdef sequent
  98. #define FSCALE    1000.0
  99. #endif
  100.  
  101. #ifdef sgi
  102. #define FSCALE    1024.0
  103. #endif
  104.  
  105. #if defined(sony) && OSMAJORVERSION == 4
  106. #ifdef mips
  107. #include <sys/fixpoint.h>
  108. #else
  109. #include <sys/param.h>
  110. #endif
  111. #endif
  112.  
  113. #ifdef SVR4
  114. #ifndef FSCALE
  115. #define FSCALE    (1 << 8)
  116. #endif
  117. #endif
  118.  
  119. #ifdef X_NOT_POSIX
  120. extern long lseek();
  121. #endif
  122. extern void exit();
  123.  
  124. static xload_error();
  125.  
  126.  
  127. #ifdef apollo
  128. #include <apollo/base.h>
  129. #include <apollo/time.h>
  130. typedef struct {
  131.     short        state;        /* ready, waiting, etc. */
  132.     pinteger    usr;        /* user sr */
  133.     linteger    upc;        /* user pc */
  134.     linteger    usp;        /* user stack pointer */
  135.     linteger    usb;        /* user sb ptr (A6) */
  136.     time_$clock_t    cpu_total;    /* cumulative cpu used by process */
  137.     unsigned short    priority;    /* process priority */
  138.     } proc1_$info_t;
  139.  
  140. void proc1_$get_cput(
  141.     time_$clock_t    *cput
  142. );
  143.  
  144. void proc1_$get_info(
  145.     short        &pid,
  146.     proc1_$info_t    *info,
  147.     status_$t    *sts
  148. );
  149.  
  150. static int     lastNullCpu;
  151. static int     lastClock;
  152.  
  153. void InitLoadPoint()                /* Apollo version */
  154. {
  155.      time_$clock_t  timeNow;
  156.      proc1_$info_t  info;
  157.      status_$t      st;
  158.  
  159.      proc1_$get_info( (short) 2, &info, &st );
  160.      time_$clock( &timeNow );
  161.  
  162.      lastClock = timeNow.low32;
  163.      lastNullCpu = info.cpu_total.low32;
  164. }
  165.  
  166. /* ARGSUSED */
  167. void GetLoadPoint( w, closure, call_data )     /* Apollo version */
  168.      Widget    w;        /* unused */
  169.      caddr_t    closure;    /* unused */
  170.      caddr_t    call_data;    /* pointer to (double) return value */
  171. {
  172.      time_$clock_t  timeNow;
  173.      double         temp;
  174.      proc1_$info_t  info;
  175.      status_$t      st;
  176.  
  177.      proc1_$get_info( (short) 2, &info, &st );
  178.      time_$clock( &timeNow );
  179.  
  180.      temp = info.cpu_total.low32 - lastNullCpu;
  181.      *(double *)call_data = 1.0 - temp / (timeNow.low32 - lastClock);
  182.  
  183.      lastClock = timeNow.low32;
  184.      lastNullCpu = info.cpu_total.low32;
  185. }
  186. #else /* not apollo */
  187. #if defined(SYSV) && defined(SYSV386)
  188. /*
  189.  * inspired by 'avgload' by John F. Haugh II
  190.  */
  191. #include <sys/param.h>
  192. #include <sys/buf.h>
  193. #include <sys/immu.h>
  194. #include <sys/region.h>
  195. #include <sys/var.h>
  196. #include <sys/proc.h>
  197. #define KERNEL_FILE "/unix"
  198. #define KMEM_FILE "/dev/kmem"
  199. #define VAR_NAME "v"
  200. #define PROC_NAME "proc"
  201. #define BUF_NAME "buf"
  202. #define DECAY 0.8
  203. struct nlist namelist[] = {
  204.   {VAR_NAME},
  205.   {PROC_NAME},
  206.   {BUF_NAME},
  207.   {0},
  208. };
  209.  
  210. static int kmem;
  211. static struct var v;
  212. static struct proc *p;
  213. static caddr_t first_buf, last_buf;
  214.  
  215. void InitLoadPoint()                /* SYSV386 version */
  216. {
  217.     int i;
  218.  
  219.     nlist( KERNEL_FILE, namelist);
  220.  
  221.     for (i=0; namelist[i].n_name; i++) 
  222.     if (namelist[i].n_value == 0)
  223.         xload_error("cannot get name list from", KERNEL_FILE);
  224.  
  225.     if ((kmem = open(KMEM_FILE, O_RDONLY)) < 0)
  226.     xload_error("cannot open", KMEM_FILE);
  227.  
  228.     if (lseek(kmem, namelist[0].n_value, 0) == -1)
  229.     xload_error("cannot seek", VAR_NAME);
  230.  
  231.     if (read(kmem, &v, sizeof(v)) != sizeof(v))
  232.     xload_error("cannot read", VAR_NAME);
  233.  
  234.     if ((p=(struct proc *)malloc(v.v_proc*sizeof(*p))) == NULL)
  235.     xload_error("cannot allocat space for", PROC_NAME);
  236.       
  237.     first_buf = (caddr_t) namelist[2].n_value;
  238.     last_buf  = first_buf + v.v_buf * sizeof(struct buf);
  239. }
  240.     
  241. /* ARGSUSED */
  242. void GetLoadPoint( w, closure, call_data )    /* SYSV386 version */
  243. Widget    w;        /* unused */
  244. caddr_t    closure;    /* unused */
  245. caddr_t    call_data;    /* pointer to (double) return value */
  246. {
  247.     double *loadavg = (double *)call_data;
  248.     static double avenrun = 0.0;
  249.     int i, nproc, size;
  250.     
  251.     (void) lseek(kmem, namelist[0].n_value, 0);
  252.     (void) read(kmem, &v, sizeof(v));
  253.  
  254.     size = (struct proc *)v.ve_proc - (struct proc *)namelist[1].n_value;
  255.  
  256.     (void) lseek(kmem, namelist[1].n_value, 0);
  257.     (void) read(kmem, p, size * sizeof(struct proc));
  258.  
  259.     for (nproc = 0, i=0; i<size; i++) 
  260.       if ((p[i].p_stat == SRUN) ||
  261.           (p[i].p_stat == SIDL) ||
  262.           (p[i].p_stat == SXBRK) ||
  263.           (p[i].p_stat == SSLEEP && (p[i].p_pri < PZERO) &&
  264.            (p[i].p_wchan >= first_buf) && (p[i].p_wchan < last_buf)))
  265.         nproc++;
  266.  
  267.     /* update the load average using a decay filter */
  268.     avenrun = DECAY * avenrun + nproc * (1.0 - DECAY);
  269.     *loadavg = avenrun;
  270.  
  271.     return;
  272. }
  273. #else /* not (SYSV && SYSV386) */
  274. #ifdef KVM_ROUTINES
  275. /*
  276.  *    Sun 386i Code - abstracted to see the wood for the trees
  277.  */
  278.  
  279. static struct nlist nl[2];
  280. static kvm_t *kd;
  281.  
  282. void
  283. InitLoadPoint()                    /* Sun 386i version */
  284. {
  285.     kd = kvm_open("/vmunix", NULL, NULL, O_RDONLY, "Load Widget");
  286.     if (kd == (kvm_t *)0) {
  287.     xload_error("cannot get access to kernel address space");
  288.     }
  289.     
  290.     nl[0].n_name = "avenrun";
  291.     nl[1].n_name = NULL;
  292.     
  293.     if (kvm_nlist(kd, nl) != 0) {
  294.     xload_error("cannot get name list");
  295.     }
  296.     
  297.     if (nl[0].n_value == 0) {
  298.     xload_error("Cannot find address for avenrun in the kernel\n");
  299.     }
  300. }
  301.  
  302. /* ARGSUSED */
  303. void 
  304. GetLoadPoint( w, closure, call_data )         /* Sun 386i version */
  305. Widget    w;        /* unused */
  306. XtPointer closure;    /* unused */
  307. XtPointer call_data;    /* pointer to (double) return value */
  308. {
  309.     double *loadavg = (double *)call_data;
  310.     long    temp;
  311.  
  312.     if (kvm_read(kd, nl[0].n_value, (char *)&temp, sizeof (temp)) != 
  313.     sizeof (temp)) {
  314.     xload_error("Kernel read error");
  315.     }
  316.     *loadavg = (double)temp/FSCALE;
  317. }
  318. #else /* not KVM_ROUTINES */
  319. #ifdef LOADSTUB
  320.  
  321. void InitLoadPoint()
  322. {
  323. }
  324.  
  325. /* ARGSUSED */
  326. void GetLoadPoint( w, closure, call_data )
  327.      Widget    w;        /* unused */
  328.      caddr_t    closure;    /* unused */
  329.      caddr_t    call_data;    /* pointer to (double) return value */
  330. {
  331.     *(double *)call_data = 1.0;
  332. }
  333.  
  334. #else /* not LOADSTUB */
  335. #ifdef linux
  336.  
  337. void InitLoadPoint()
  338. {
  339. }
  340.  
  341. /* ARGSUSED */
  342. void GetLoadPoint( w, closure, call_data )
  343.      Widget    w;        /* unused */
  344.      caddr_t    closure;    /* unused */
  345.      caddr_t    call_data;    /* pointer to (double) return value */
  346. {
  347.     FILE *f;
  348.     double value;
  349. #ifdef MEMORY
  350.     char buf[80];
  351.     double avail;
  352.     int i, j;
  353.  
  354.     if (!(f = fopen ("/proc/meminfo", "r"))) {
  355.         perror("xmem : cannot open /proc/meminfo ");
  356.         exit(1);
  357.     }
  358.     if (fgets(buf, sizeof(buf), f) != buf ||
  359.             fgets(buf, sizeof(buf), f) != buf ||
  360.             sscanf(buf, "%*s %lf %*d %lf", &value, &avail) != 2 ||
  361.             fgets(buf, sizeof(buf), f) != buf ||
  362.             sscanf(buf, "%*s %d %*d %d", &i, &j) !=  2) {
  363.         perror("xmem : /proc/meminfo is in a bad format ");
  364.         exit(1);
  365.     }
  366.  
  367.     *(double *)call_data = 10.0 * (avail + (double )j) /
  368.         (value + (double )i);
  369. #else
  370. #ifdef IDLE
  371.     static int last_idle = 0;
  372.     static int last_time = 0;
  373.     int idle, idle100;
  374.     int time, time100;
  375.     int idle_diff;
  376.     int time_diff;
  377.     double rodummy;
  378.     if (!(f = fopen ("/proc/uptime", "r"))) {
  379.       perror("xidle : cannot open /proc/uptime ");
  380.       exit(1);
  381.     }
  382.     
  383.     fscanf( f, "%d.%d %d.%d", &time100, &time, &idle100, &idle );
  384.     time += 100 * time100;
  385.     idle += 100 * idle100;
  386.     
  387.     idle_diff = idle - last_idle;
  388.     time_diff = time - last_time;
  389.     
  390.     last_idle = idle;
  391.     last_time = time;
  392.     if (idle_diff > 0 && time_diff > 0 )
  393.       rodummy = (double)idle_diff / (double)time_diff;
  394.     else
  395.       rodummy=0.0;
  396.     
  397.     *(double*) call_data = 0.95*(1.0-rodummy);
  398. #else
  399.     if (!(f = fopen ("/proc/loadavg", "r"))) {
  400.         perror("xload : cannot open /proc/loadavg ");
  401.         exit(1);
  402.     }
  403.  
  404.     fscanf(f, "%lf", (double *) call_data);
  405. #endif
  406. #endif
  407.     fclose(f);
  408. }
  409. #else
  410.  
  411. #ifndef KMEM_FILE
  412. #define KMEM_FILE "/dev/kmem"
  413. #endif
  414.  
  415. #ifndef KERNEL_FILE
  416.  
  417. #ifdef alliant
  418. #define KERNEL_FILE "/vmunix"
  419. #endif /* alliant */
  420.  
  421. #ifdef CRAY
  422. #define KERNEL_FILE "/unicos"
  423. #endif /* CRAY */
  424.  
  425. #ifdef hpux
  426. #define KERNEL_FILE "/hp-ux"
  427. #endif /* hpux */
  428.  
  429. #ifdef macII
  430. #define KERNEL_FILE "/unix"
  431. #endif /* macII */
  432.  
  433. #ifdef umips
  434. # ifdef SYSTYPE_SYSV
  435. # define KERNEL_FILE "/unix"
  436. # else
  437. # define KERNEL_FILE "/vmunix"
  438. # endif /* SYSTYPE_SYSV */
  439. #endif /* umips */
  440.  
  441. #ifdef sequent
  442. #define KERNEL_FILE "/dynix"
  443. #endif /* sequent */
  444.  
  445. #ifdef hcx
  446. #define KERNEL_FILE "/unix"
  447. #endif /* hcx */
  448.  
  449. #ifdef MOTOROLA
  450. #if defined(SYSV) && defined(m68k)
  451. #define KERNEL_FILE "/sysV68"
  452. #endif
  453. #if defined(SYSV) && defined(m88k)
  454. #define KERNEL_FILE "/unix"
  455. #endif
  456. #ifdef SVR4
  457. #define KERNEL_FILE "/unix"
  458. #endif
  459. #endif /* MOTOROLA */
  460.  
  461. /*
  462.  * provide default for everyone else
  463.  */
  464. #ifndef KERNEL_FILE
  465. #ifdef SVR4
  466. #define KERNEL_FILE "/stand/unix"
  467. #else
  468. #ifdef SYSV
  469. #define KERNEL_FILE "/unix"
  470. #else
  471. #define KERNEL_FILE "/vmunix"
  472. #endif /* SYSV */
  473. #endif /* SVR4 */
  474. #endif /* KERNEL_FILE */
  475. #endif /* KERNEL_FILE */
  476.  
  477.  
  478. #ifndef KERNEL_LOAD_VARIABLE
  479. #    ifdef alliant
  480. #        define KERNEL_LOAD_VARIABLE "_Loadavg"
  481. #    endif /* alliant */
  482.  
  483. #    ifdef CRAY
  484. #        if defined(CRAY2) && OSMAJORVERSION == 4
  485. #            define KERNEL_LOAD_VARIABLE "avenrun"
  486. #        else
  487. #            define KERNEL_LOAD_VARIABLE "sysinfo"
  488. #            define SYSINFO
  489. #        endif /* defined(CRAY2) && OSMAJORVERSION == 4 */
  490. #    endif /* CRAY */
  491.  
  492. #    ifdef hpux
  493. #        ifdef hp9000s800
  494. #            define KERNEL_LOAD_VARIABLE "avenrun"
  495. #        endif /* hp9000s800 */
  496. #    endif /* hpux */
  497.  
  498. #    ifdef umips
  499. #        ifdef SYSTYPE_SYSV
  500. #            define KERNEL_LOAD_VARIABLE "avenrun"
  501. #        else
  502. #            define KERNEL_LOAD_VARIABLE "_avenrun"
  503. #        endif /* SYSTYPE_SYSV */
  504. #    endif /* umips */
  505.  
  506. #    ifdef sgi
  507. #     define KERNEL_LOAD_VARIABLE "avenrun"
  508. #    endif /* sgi */
  509.  
  510. #    ifdef AIXV3
  511. #        define KERNEL_LOAD_VARIABLE "sysinfo"
  512. #    endif /* AIXV3 */
  513.  
  514. #    ifdef MOTOROLA
  515. #        if defined(SYSV) && defined(m68k)
  516. #            define KERNEL_LOAD_VARIABLE "sysinfo"
  517. #        endif
  518. #        if defined(SYSV) && defined(m88k)
  519. #            define KERNEL_LOAD_VARIABLE "_sysinfo"
  520. #        endif
  521. #        ifdef SVR4
  522. #            define KERNEL_LOAD_VARIABLE "avenrun"
  523. #        endif
  524. #    endif /* MOTOROLA */
  525.  
  526. #endif /* KERNEL_LOAD_VARIABLE */
  527.  
  528. /*
  529.  * provide default for everyone else
  530.  */
  531.  
  532. #ifndef KERNEL_LOAD_VARIABLE
  533. #    ifdef USG
  534. #        define KERNEL_LOAD_VARIABLE "sysinfo"
  535. #        define SYSINFO
  536. #    else
  537. #    ifdef SVR4
  538. #        define KERNEL_LOAD_VARIABLE "avenrun"
  539. #    else
  540. #        define KERNEL_LOAD_VARIABLE "_avenrun"
  541. #    endif
  542. #    endif
  543. #endif /* KERNEL_LOAD_VARIABLE */
  544.  
  545. #ifdef macII
  546. static struct var v;
  547. static int pad[2];    /* This padding is needed if xload compiled on */
  548.             /* a/ux 1.1 is executed on a/ux 1.0, because */
  549.             /* the var structure had too much padding in 1.0, */
  550.             /* so the 1.0 kernel writes past the end of the 1.1 */
  551.             /* var structure in the uvar() call. */
  552. static struct nlist nl[2];
  553. static struct lavnum vec[3];
  554. #else /* not macII */
  555. static struct nlist namelist[] = {        /* namelist for vmunix grubbing */
  556. #define LOADAV 0
  557.     {KERNEL_LOAD_VARIABLE},
  558.     {0}
  559. };
  560. #endif /* macII */
  561.  
  562. static kmem;
  563. static long loadavg_seek;
  564.  
  565. InitLoadPoint()
  566. {
  567. #ifdef macII
  568.     extern nlist();
  569.  
  570.     int i;
  571.  
  572.     strcpy(nl[0].n_name, "avenrun");
  573.     nl[1].n_name[0] = '\0';
  574.  
  575.     kmem = open(KMEM_FILE, O_RDONLY);
  576.     if (kmem < 0) {
  577.     xload_error("cannot open", KMEM_FILE);
  578.     }
  579.  
  580.     uvar(&v);
  581.  
  582.     if (nlist( KERNEL_FILE, nl) != 0) {
  583.     xload_error("cannot get name list from", KERNEL_FILE);
  584.     }
  585.     for (i = 0; i < 2; i++) {
  586.     nl[i].n_value = (int)nl[i].n_value - v.v_kvoffset;
  587.     }
  588. #else /* not macII */
  589. #if (!defined(SVR4) || !defined(__STDC__)) && !defined(sgi) && !defined(MOTOROLA)
  590.     extern void nlist();
  591. #endif
  592.  
  593. #ifdef AIXV3
  594.     knlist( namelist, 1, sizeof(struct nlist));
  595. #else    
  596.     nlist( KERNEL_FILE, namelist);
  597. #endif
  598.     /*
  599.      * Some systems appear to set only one of these to Zero if the entry could
  600.      * not be found, I hope no_one returns Zero as a good value, or bad things
  601.      * will happen to you.  (I have a hard time believing the value will
  602.      * ever really be zero anyway).   CDP 5/17/89.
  603.      */
  604. #ifdef hcx
  605.     if (namelist[LOADAV].n_type == 0 &&
  606. #else
  607.     if (namelist[LOADAV].n_type == 0 ||
  608. #endif /* hcx */
  609.     namelist[LOADAV].n_value == 0) {
  610.     xload_error("cannot get name list from", KERNEL_FILE);
  611.     exit(-1);
  612.     }
  613.     loadavg_seek = namelist[LOADAV].n_value;
  614. #if defined(umips) && defined(SYSTYPE_SYSV)
  615.     loadavg_seek &= 0x7fffffff;
  616. #endif /* umips && SYSTYPE_SYSV */
  617. #if (defined(CRAY) && defined(SYSINFO))
  618.     loadavg_seek += ((char *) (((struct sysinfo *)NULL)->avenrun)) -
  619.     ((char *) NULL);
  620. #endif /* CRAY && SYSINFO */
  621.   
  622.     kmem = open(KMEM_FILE, O_RDONLY);
  623.     if (kmem < 0) xload_error("cannot open", KMEM_FILE);
  624. #endif /* macII else */
  625. }
  626.  
  627. /* ARGSUSED */
  628. void GetLoadPoint( w, closure, call_data )
  629.      Widget    w;        /* unused */
  630.      caddr_t    closure;    /* unused */
  631.      caddr_t    call_data;    /* pointer to (double) return value */
  632. {
  633.       double *loadavg = (double *)call_data;
  634.  
  635. #ifdef macII
  636.     lseek(kmem, (long)nl[X_AVENRUN].n_value, 0);
  637. #else
  638.     (void) lseek(kmem, loadavg_seek, 0);
  639. #endif
  640.  
  641. #if defined(sun) || defined (UTEK) || defined(sequent) || defined(alliant) || defined(SVR4) || defined(sgi) || defined(hcx)
  642.     {
  643.         long temp;
  644.         (void) read(kmem, (char *)&temp, sizeof(long));
  645.         *loadavg = (double)temp/FSCALE;
  646.     }
  647. #else /* else not sun or UTEK or sequent or alliant or SVR4 or sgi or hcx */
  648. # ifdef macII
  649.         {
  650.                 read(kmem, vec, 3*sizeof(struct lavnum));
  651.                 *loadavg = fxtod(0);
  652.         }
  653. # else /* else not macII */
  654. #  if defined(umips) || (defined(ultrix) && defined(mips))
  655.     {
  656.         fix temp;
  657.         (void) read(kmem, (char *)&temp, sizeof(fix));
  658.         *loadavg = FIX_TO_DBL(temp);
  659.     }
  660. #  else /* not umips or ultrix risc */
  661. #    ifdef AIXV3
  662.         {
  663.           struct sysinfo sysinfo_now;
  664.           struct sysinfo sysinfo_last;
  665.           static firsttime = TRUE;
  666.           static double runavg = 0.0, swpavg = 0.0;
  667.  
  668.           (void) lseek(kmem, loadavg_seek, 0);
  669.           (void) read(kmem, (char *)&sysinfo_last, sizeof(struct sysinfo));
  670.           if (firsttime)
  671.             {
  672.               *loadavg = 0.0;
  673.               firsttime = FALSE;
  674.             }
  675.           else
  676.             {
  677.               sleep(1);
  678.               (void) lseek(kmem, loadavg_seek, 0);
  679.               (void) read(kmem, (char *)&sysinfo_now, sizeof(struct sysinfo));
  680.               runavg *= 0.8; swpavg *= 0.8;
  681.               if (sysinfo_now.runocc != sysinfo_last.runocc)
  682.                 runavg += 0.2*((sysinfo_now.runque - sysinfo_last.runque - 1)
  683.                           /(double)(sysinfo_now.runocc - sysinfo_last.runocc));
  684.               if (sysinfo_now.swpocc != sysinfo_last.swpocc)
  685.                 swpavg += 0.2*((sysinfo_now.swpque - sysinfo_last.swpque)
  686.                           /(double)(sysinfo_now.swpocc - sysinfo_last.swpocc));
  687.               *loadavg = runavg + swpavg;
  688.               sysinfo_last = sysinfo_now;
  689.             }
  690.           /* otherwise we leave load alone. */
  691.         }
  692. #    else /* not AIXV3 */
  693. #      if defined(MOTOROLA) && defined(SYSV)
  694.     {
  695.         static int init = 0;
  696.         static kmem;
  697.         static long loadavg_seek;
  698.         static xload_error();
  699.  
  700. #define CEXP    0.25            /* Constant used for load averaging */
  701.  
  702.         struct sysinfo sysinfod;
  703.         static double oldloadavg;
  704.         static double cexp = CEXP;
  705.         static long sv_rq, sv_oc;   /* save old values */
  706.         double rq, oc;              /* amount values have changed */
  707.  
  708.         if (!init)
  709.         {
  710.             if (nlist(KERNEL_FILE,namelist) == -1)
  711.             {
  712.                 perror("xload: nlist()");
  713.                 xload_error("cannot get name list from", KERNEL_FILE);
  714.             }
  715.             loadavg_seek = namelist[0].n_value;
  716.  
  717.             kmem = open(KMEM_FILE, O_RDONLY);
  718.             if (kmem < 0)
  719.             {
  720.                 perror("xload: open()");
  721.                 xload_error("cannot open", KMEM_FILE);
  722.             }
  723.         }
  724.  
  725.         lseek(kmem, loadavg_seek, 0);
  726.         if (read(kmem, &sysinfod, (int) sizeof (struct sysinfo)) == -1)
  727.         {
  728.              perror("xload: read() SYSINFONL");
  729.              xload_error("read failed from", KMEM_FILE);
  730.         }
  731.  
  732.         if (!init)
  733.         {
  734.             init = 1;
  735.             sv_rq = sysinfod.runque;
  736.             sv_oc = sysinfod.runocc;
  737.             oldloadavg = *loadavg = 0.0;
  738.             return;
  739.         }
  740.         /*
  741.          * calculate the amount the values have
  742.          * changed since last update
  743.          */
  744.         rq = (double) sysinfod.runque - sv_rq;
  745.         oc = (double) sysinfod.runocc - sv_oc;
  746.  
  747.         /*
  748.          * save old values for next time
  749.          */
  750.         sv_rq = sysinfod.runque;
  751.         sv_oc = sysinfod.runocc;
  752.  
  753.         if (oc == 0.0)          /* avoid divide by zero  */
  754.         {
  755.                 *loadavg = (1.0 - cexp) * oldloadavg;
  756.  
  757.         }
  758.         else
  759.         {
  760.                 *loadavg = ((1.0 - cexp) * oldloadavg) ((rq / oc) * cexp);
  761.         }
  762.         oldloadavg = *loadavg;
  763.     }
  764. #      else /* not MOTOROLA */
  765. #     if defined(sony) && OSMAJORVERSION == 4
  766. #      ifdef mips
  767.     {
  768.         fix temp;
  769.         (void) read(kmem, (char *)&temp, sizeof(fix));
  770.         *loadavg = FIX_TO_DBL(temp);
  771.     }
  772. #      else /* not mips */
  773.     {
  774.         long temp;
  775.         (void) read(kmem, (char *)&temp, sizeof(long));
  776.         *loadavg = (double)temp/FSCALE;
  777.     }
  778. #      endif /* mips */
  779. #     else /* not sony NEWSOS4 */
  780.     (void) read(kmem, (char *)loadavg, sizeof(double));
  781. #        endif /* sony NEWOS4 */
  782. #      endif /* MOTOROLA else */
  783. #    endif /* AIXV3 else */
  784. #  endif /* umips else */
  785. # endif /* macII else */
  786. #endif /* sun else */
  787.     return;
  788. }
  789. #endif /* linux else */
  790. #endif /* LOADSTUB else */
  791. #endif /* KVM_ROUTINES else */
  792. #endif /* SYSV && SYSV386 else */
  793.  
  794. static xload_error(str1, str2)
  795. char *str1, *str2;
  796. {
  797.     (void) fprintf(stderr,"xload: %s %s\n", str1, str2);
  798.     exit(-1);
  799. }
  800.  
  801. #endif /* apollo else */
  802.  
  803.