|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T g
Length: 12365 (0x304d) Types: TextFile Names: »getloadavg.c«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit └─⟦bfebc70e2⟧ »EurOpenD3/mail/sendmail-5.65b+IDA-1.4.3.tar.Z« └─⟦f9e35cd84⟧ └─⟦this⟧ »sendmail/src/getloadavg.c«
/* * Copyright 1989 Massachusetts Institute of Technology * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. M.I.T. makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T. * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Authors: Many and varied... */ #include <sys/types.h> #ifdef DGUX #include <sys/dg_sys_info.h> int getloadavg( call_data ) caddr_t call_data; /* pointer to (double) return value */ { struct dg_sys_info_load_info load_info; dg_sys_info(&load_info, DG_SYS_INFO_LOAD_INFO_TYPE, DG_SYS_INFO_LOAD_VERSION_0); *(double *)call_data = load_info.one_minute; } #else /* DGUX */ #ifdef UMAX /* * * FOR: Encore multimax UMAX 4.3. * * Extracted from get_stats() (written by John Robert LoVerso) * by Neil Rickert. * * Use inq_stats() to determine boottime, load average * */ #include <sys/param.h> /* */ #include <sys/time.h> /* */ #include <inq_stats/statistics.h> #include <inq_stats/procstats.h> /* * see dimension of ps_nrun[] in procstats.h */ #ifndef PS_NRUNSIZE #define PS_NRUNSIZE 300 #endif /* * Each entry in ps_nrun[] is count of runnable processes sampled every * 5 seconds. period[] contains the number of samples to use for the * intervals of {1,5,15} minutes. cexp[] contains constans for exponential * decay. */ #define period 12 int getloadavg( call_data ) caddr_t call_data; /* pointer to (double) return value */ { struct stat_descr Proc_info; struct proc_summary Proc_sum_data; register int i, index, interval; /* * struct to get process summary data, * esp circular buffer containing counts of runnable processes */ Proc_info.sd_next = NULL; Proc_info.sd_subsys = SUBSYS_PROC; Proc_info.sd_type = PROCTYPE_SUMMARY; Proc_info.sd_addr = (char *) &Proc_sum_data; Proc_info.sd_size = sizeof (struct proc_summary); Proc_info.sd_sizeused = 0; /* * fill in Boot_data and Proc_sum_data structures */ if (inq_stats(1, &Proc_info) != 0) { perror("inq_stats"); exit(1); } /* * fastest (inverse shared sum) loop */ index = Proc_sum_data.ps_nrunidx; interval = 0; *(double *)call_data = 0.0; for (; interval < period; interval++) { *(double *)call_data += Proc_sum_data.ps_nrun[index]; if (--index < 0) index = PS_NRUNSIZE-1; } *(double *)call_data /= period; } #else /* UMAX */ /* * Get open(2) constants */ #ifdef SYSV #ifndef macII #include <fcntl.h> #endif #endif /* SYSV */ #include <sys/file.h> #ifdef USG #include <unistd.h> #endif #ifdef att #define LOADSTUB #endif #ifdef apollo #include <apollo/base.h> #include <apollo/time.h> typedef struct { short state; /* ready, waiting, etc. */ pinteger usr; /* user sr */ linteger upc; /* user pc */ linteger usp; /* user stack pointer */ linteger usb; /* user sb ptr (A6) */ time_$clock_t cpu_total; /* cumulative cpu used by process */ unsigned short priority; /* process priority */ } proc1_$info_t; /* Enable function prototypes for ANSI C and C++ */ #if defined(__STDC__) || defined(c_plusplus) || defined(__cplusplus) # define _PROTOTYPES #endif void proc1_$get_cput( #ifdef _PROTOTYPES time_$clock_t *cput #endif ); void proc1_$get_info( #ifdef _PROTOTYPES short &pid, proc1_$info_t *info, status_$t *sts #endif ); #ifdef _PROTOTYPES # undef _PROTOTYPES #endif #endif /* apollo */ #ifndef macII #ifndef apollo #ifndef LOADSTUB #include <nlist.h> #endif /* LOADSTUB */ #endif /* apollo */ #endif /* macII */ #ifdef sun # include <sys/param.h> # ifdef i386 # include <kvm.h> # define KVM_ROUTINES # endif /* i386 */ #endif #if defined(mips) && !defined(sgi) #include <sys/fixpoint.h> #endif #ifdef CRAY #include <sys/param.h> #include <sys/sysinfo.h> #undef n_type #define n_type n_value #endif /* CRAY */ #ifdef vax #include <sys/param.h> #endif /* sequent */ #ifdef sequent #include <sys/vm.h> #endif /* sequent */ #ifdef macII #include <a.out.h> #include <sys/var.h> #define X_AVENRUN 0 #define fxtod(i) (vec[i].high+(vec[i].low/65536.0)) struct lavnum { unsigned short high; unsigned short low; }; #endif /* macII */ #if defined(UTEK) || defined(alliant) #define FSCALE 100.0 #endif #if defined(sequent) && !defined(FSCALE) #define FSCALE 1000.0 #endif #ifdef hp9000 #include <sys/param.h> #endif #ifndef FSCALE #define FSHIFT 8 /* bits to right of fixed binary point */ #define FSCALE (1<<FSHIFT) #endif /* not FSCALE */ extern long lseek(); extern void exit(); #if apollo /* ARGSUSED */ int getloadavg( call_data ) caddr_t call_data; /* pointer to (double) return value */ { static int firstTime = 1; static int lastNullCpu; static int lastClock; time_$clock_t timeNow; double temp; proc1_$info_t info; status_$t st; proc1_$get_info( (short) 2, &info, &st ); time_$clock( &timeNow ); if (firstTime) { *(double *)call_data = 1.0; firstTime = 0; } else { temp = info.cpu_total.low32 - lastNullCpu; *(double *)call_data = 1.0 - temp / (timeNow.low32 - lastClock); } lastClock = timeNow.low32; lastNullCpu = info.cpu_total.low32; return(0); } #else #ifdef KVM_ROUTINES /* * Sun 386i Code - abstracted to see the wood for the trees */ /* ARGSUSED */ void getloadavg( call_data ) caddr_t call_data; /* pointer to (double) return value */ { double *loadavg = (double *)call_data; long temp; static int init = 0; static struct nlist nl[2]; static kvm_t *kd; if (!init) { kd = kvm_open("/vmunix", NULL, NULL, O_RDONLY, NULL); if (kd == (kvm_t *)0) { return (-1); } nl[0].n_name = "avenrun"; nl[1].n_name = NULL; if (kvm_nlist(kd, nl) != 0) { return (-1); } init = 1; } if (nl[0].n_value == 0) { return (-1); } if (kvm_read(kd, nl[0].n_value, (char *)&temp, sizeof (temp)) != sizeof (temp)) { return (-1); } *loadavg = (double)temp/FSCALE; return(0); } #else /* KVM_ROUTINES */ #ifdef LOADSTUB /* ARGSUSED */ int getloadavg( call_data ) caddr_t call_data; /* pointer to (double) return value */ { *(double *)call_data = 1.0; } #else /* LOADSTUB */ #ifndef KMEM_FILE #define KMEM_FILE "/dev/kmem" #endif #ifndef KERNEL_FILE #ifdef alliant #define KERNEL_FILE "/unix" #endif /* alliant */ #ifdef CRAY #define KERNEL_FILE "/unicos" #endif /* CRAY */ #ifdef hpux #define KERNEL_FILE "/hp-ux" #endif /* hpux */ #ifdef macII #define KERNEL_FILE "/unix" #endif /* macII */ #ifdef mips # ifdef SYSTYPE_SYSV # define KERNEL_FILE "/unix" # else # define KERNEL_FILE "/vmunix" # endif /* SYSTYPE_SYSV */ #endif /* mips */ #ifdef sequent #define KERNEL_FILE "/dynix" #endif /* sequent */ /* * provide default for everyone else */ #ifndef KERNEL_FILE #ifdef SYSV #define KERNEL_FILE "/unix" #else #define KERNEL_FILE "/vmunix" #endif /* SYSV */ #endif /* KERNEL_FILE */ #endif /* KERNEL_FILE */ #ifndef KERNEL_LOAD_VARIABLE /* * provide default */ # ifdef USG # define KERNEL_LOAD_VARIABLE "sysinfo" # define SYSINFO # else # define KERNEL_LOAD_VARIABLE "_avenrun" # endif # ifdef alliant # undef KERNEL_LOAD_VARIABLE # define KERNEL_LOAD_VARIABLE "_Loadave" # endif /* alliant */ # ifdef CRAY # if defined(CRAY2) && OSMAJORVERSION == 4 # undef KERNEL_LOAD_VARIABLE # define KERNEL_LOAD_VARIABLE "avenrun" # else # undef KERNEL_LOAD_VARIABLE # define KERNEL_LOAD_VARIABLE "sysinfo" # define SYSINFO # endif /* defined(CRAY2) && OSMAJORVERSION == 4 */ # endif /* CRAY */ # ifdef hpux # ifdef hp9000s800 # undef KERNEL_LOAD_VARIABLE # define KERNEL_LOAD_VARIABLE "avenrun" # endif /* hp9000s800 */ # endif /* hpux */ # ifdef mips # ifdef SYSTYPE_SYSV # undef KERNEL_LOAD_VARIABLE # define KERNEL_LOAD_VARIABLE "avenrun" # else # undef KERNEL_LOAD_VARIABLE # define KERNEL_LOAD_VARIABLE "_avenrun" # endif /* SYSTYPE_SYSV */ # endif /* mips */ # ifdef sequent # define KERNEL_FILE "/dynix" # endif /* sequent */ #endif /* KERNEL_LOAD_VARIABLE */ #ifdef macII struct var v; static int pad[2]; /* This padding is needed if getloadavg compiled on */ /* a/ux 1.1 is executed on a/ux 1.0, because */ /* the var structure had too much padding in 1.0, */ /* so the 1.0 kernel writes past the end of the 1.1 */ /* var structure in the uvar() call. */ static struct nlist nl[2]; static struct lavnum vec[3]; #else /* not macII */ static struct nlist namelist[] = { /* namelist for vmunix grubbing */ #define LOADAV 0 # ifdef NeXT {{KERNEL_LOAD_VARIABLE}}, {{0},0} # else /* !NeXT */ {KERNEL_LOAD_VARIABLE}, {0} # endif /* NeXT */ }; #endif /* macII */ /* ARGSUSED */ int getloadavg( call_data ) caddr_t call_data; /* pointer to (double) return value */ { double *loadavg = (double *)call_data; static int init = 0; static kmem; static long loadavg_seek; #ifdef macII extern nlist(); if(!init) { int i; strcpy(nl[0].n_name, "avenrun"); nl[1].n_name[0] = '\0'; kmem = open(KMEM_FILE, O_RDONLY); if (kmem < 0) { return (-1); } uvar(&v); if (nlist( KERNEL_FILE, nl) != 0) { return (-1); } for (i = 0; i < 2; i++) { nl[i].n_value = (int)nl[i].n_value - v.v_kvoffset; } init = 1; } #else /* not macII */ # if !defined(sgi) && !defined(BSD4_4) extern void nlist(); # else extern nlist(); # endif /* !sgi */ if(!init) { nlist( KERNEL_FILE, namelist); /* * Some systems appear to set only one of these to Zero if the entry could * not be found, I hope no_one returns Zero as a good value, or bad things * will happen to you. (I have a hard time believing the value will * ever really be zero anyway). CDP 5/17/89. */ if (namelist[LOADAV].n_type == 0 || namelist[LOADAV].n_value == 0) { return (-1); } loadavg_seek = namelist[LOADAV].n_value; #if defined(mips) && defined(SYSTYPE_SYSV) loadavg_seek &= 0x7fffffff; #endif /* mips && SYSTYPE_SYSV */ #if (defined(CRAY) && defined(SYSINFO)) loadavg_seek += ((char *) (((struct sysinfo *)NULL)->avenrun)) - ((char *) NULL); #endif /* SYSINFO */ kmem = open(KMEM_FILE, O_RDONLY); if (kmem < 0) return (-1); init = 1; } (void) lseek(kmem, loadavg_seek, 0); #endif /* macII */ #if defined(sun) || defined (UTEK) || defined(sequent) || \ defined(alliant) || defined(hp9000) || defined(sgi) { long temp; (void) read(kmem, (char *)&temp, sizeof(long)); *loadavg = (double)temp/FSCALE; } #else /* else not sun */ # ifdef macII { lseek(kmem, (long)nl[X_AVENRUN].n_value, 0); read(kmem, vec, 3*sizeof(struct lavnum)); *loadavg = fxtod(0); } # else /* else not macII */ # if defined(mips) { fix temp; (void) read(kmem, (char *)&temp, sizeof(fix)); *loadavg = FIX_TO_DBL(temp); } # else /* not mips */ (void) read(kmem, (char *)loadavg, sizeof(double)); # endif /* mips */ # endif /* macII */ #endif /* sun */ return(0); } #endif /* LOADSTUB */ #endif /* KVM_ROUTINES */ #endif /* apollo */ #endif /* UMAX */ #endif /* DGUX */