📄 m_irix5.c
字号:
/* * top - a top users display for Unix * * SYNOPSIS: any uniprocessor, 32 bit SGI machine running IRIX 5.3 * * DESCRIPTION: * This is the machine-dependent module for IRIX 5.3. * It has been tested on Indys running 5.3 and Indigos running 5.3XFS * * LIBS: -lmld * CFLAGS: -DHAVE_GETOPT * * AUTHOR: Sandeep Cariapa <cariapa@sgi.com> * This is not a supported product of Silicon Graphics, Inc. * Please do not call SGI for support. * */#define _KMEMUSER#include <sys/types.h>#include <sys/time.h>#include <sys/stat.h>#include <sys/swap.h>#include <sys/proc.h>#include <sys/procfs.h>#include <sys/sysinfo.h>#include <sys/sysmp.h>#include <paths.h>#include <dirent.h>#include <stdio.h>#include <nlist.h>#include <unistd.h>#include <errno.h>#include <fcntl.h>#include "top.h"#include "machine.h"#ifdef IRIX64#define nlist nlist64#define lseek lseek64#define off_t off64_t#endif#define UNIX "/unix"#define KMEM "/dev/kmem"#define CPUSTATES 6#ifndef FSCALE#define FSHIFT 8 /* bits to right of fixed binary point */#define FSCALE (1<<FSHIFT)#endif /* FSCALE */#ifdef FIXED_LOADAVG typedef long load_avg;# define loaddouble(la) ((double)(la) / FIXED_LOADAVG)# define intload(i) ((int)((i) * FIXED_LOADAVG))#else typedef double load_avg;# define loaddouble(la) (la)# define intload(i) ((double)(i))#endif#define percent_cpu(pp) (*(double *)pp->pr_fill)#define weighted_cpu(pp) (*(double *)&pp->pr_fill[2])static int pagesize;#define pagetok(size) ((size)*pagesize)static int numcpus;/* * These definitions control the format of the per-process area */static char header[] = " PID X PRI NICE SIZE RES STATE TIME WCPU CPU COMMAND";/* 0123456 -- field to fill in starts at header+6 */#define UNAME_START 6#define Proc_format \ "%5d %-8.8s %3d %4d %5s %5s %-5s %6s %5.2f%% %5.2f%% %.16s"/* these are for detailing the process states */char *state_abbrev[] ={"", "sleep", "run\0\0\0", "zombie", "stop", "idle", "", "swap"};int process_states[8];char *procstatenames[] = { "", " sleeping, ", " running, ", " zombie, ", " stopped, ", " idle, ", "", " swapped, ", NULL};/* these are for detailing the cpu states */int cpu_states[CPUSTATES];char *cpustatenames[] = { "idle", "usr", "ker", "wait", "swp", "intr", NULL};/* these are for detailing the memory statistics */int memory_stats[5];char *memorynames[] = { "K max, ", "K avail, ", "K free, ", "K swap, ", "K free swap", NULL};/* useful externals */extern int errno;extern char *myname;extern char *sys_errlist[];extern char *format_k();extern char *format_time();extern long percentages();#define X_AVENRUN 0#define X_NPROC 1#define X_FREEMEM 2#define X_MAXMEM 3#define X_AVAILRMEM 4#define X_MPID 5static struct nlist nlst[] = {{ "avenrun" }, /* 0. Array containing the 3 load averages. */{ "nproc" }, /* 1. Kernel parameter: Max number of processes. */{ "freemem" }, /* 2. Amount of free memory in system. */{ "maxmem" }, /* 3. Maximum amount of memory usable by system. */{ "availrmem" }, /* 4. Available real memory. */#ifndef IRIX64{ "mpid" }, /* 5. PID of last process. */#endif{ 0 }};static unsigned long avenrun_offset;static unsigned long nproc_offset;static unsigned long freemem_offset;static unsigned long maxmem_offset;static unsigned long availrmem_offset;static unsigned long mpid_offset;double load[3];char fmt[MAX_COLS];static int kmem;static int nproc;static int bytes;static struct prpsinfo *pbase;static struct prpsinfo **pref;static DIR *procdir;/* get_process_info passes back a handle. This is what it looks like: */struct handle { struct prpsinfo **next_proc;/* points to next valid proc pointer */ int remaining; /* number of pointers remaining */};static struct handle handle;void getptable();/* * Structure for keeping track of CPU times from last time around * the program. We keep these things in a hash table, which is * recreated at every cycle. */struct oldproc { pid_t oldpid; double oldtime; double oldpct; };static int oldprocs; /* size of table */static struct oldproc *oldbase;#define HASH(x) ((x << 1) % oldprocs)#define PRPSINFOSIZE (sizeof(struct prpsinfo))int machine_init(statics) struct statics *statics;{ struct oldproc *op, *endbase; if ((kmem = open(KMEM, O_RDONLY)) == -1) { perror(KMEM); return(-1); } /* get the list of symbols we want to access in the kernel */ (void) nlist(UNIX, nlst); if (nlst[0].n_type == 0) { fprintf(stderr, "%s: nlist failed\n", myname); return(-1); } /* Check if we got all of 'em. */ if (check_nlist(nlst) > 0) { return(-1); } avenrun_offset = nlst[X_AVENRUN].n_value; nproc_offset = nlst[X_NPROC].n_value; freemem_offset = nlst[X_FREEMEM].n_value; maxmem_offset = nlst[X_MAXMEM].n_value; availrmem_offset = nlst[X_AVAILRMEM].n_value;#ifndef IRIX64 mpid_offset = nlst[X_MPID].n_value;#endif /* Got to do this first so that we can map real estate for the process array. */ (void) getkval(nproc_offset, (int *) (&nproc), sizeof(nproc), "nproc"); /* allocate space for proc structure array and array of pointers */ bytes = nproc * sizeof (struct prpsinfo); pbase = (struct prpsinfo *) malloc (bytes); pref = (struct prpsinfo **) malloc (nproc * sizeof (struct prpsinfo *)); oldbase = (struct oldproc *) malloc (2 * nproc * sizeof (struct oldproc)); /* Just in case ... */ if (pbase == (struct prpsinfo *) NULL || pref == (struct prpsinfo **) NULL || oldbase == (struct oldproc *)NULL) { (void) fprintf (stderr, "%s: can't allocate sufficient memory\n", myname); return (-1); } oldprocs = 2 * nproc; endbase = oldbase + oldprocs; for (op = oldbase; op < endbase; op++) { op->oldpid = -1; } if (!(procdir = opendir (_PATH_PROCFSPI))) { (void) fprintf (stderr, "Unable to open %s\n", _PATH_PROCFSPI); return (-1); } if (chdir (_PATH_PROCFSPI)) { /* handy for later on when we're reading it */ (void) fprintf (stderr, "Unable to chdir to %s\n", _PATH_PROCFSPI); return (-1); } statics->procstate_names = procstatenames; statics->cpustate_names = cpustatenames; statics->memory_names = memorynames; pagesize = getpagesize()/1024; /* all done! */ return(0);}char *format_header(uname_field) register char *uname_field;{ register char *ptr; ptr = header + UNAME_START; while (*uname_field != '\0') { *ptr++ = *uname_field++; } return(header);}void get_system_info(si) struct system_info *si;{ register int i; int avenrun[3]; static int freemem; static int maxmem; static int availrmem; struct sysinfo sysinfo; static long cp_new[CPUSTATES]; static long cp_old[CPUSTATES]; static long cp_diff[CPUSTATES]; /* for cpu state percentages */ off_t fswap; /* current free swap in blocks */ off_t tswap; /* total swap in blocks */ (void) getkval(avenrun_offset, (int *)avenrun, sizeof(avenrun), "avenrun"); for (i = 0; i < 3; i++) { si->load_avg[i] = loaddouble (avenrun[i]); si->load_avg[i] = si->load_avg[i]/1024.0; } (void) getkval(freemem_offset, (int *) (&freemem), sizeof(freemem),"freemem"); (void) getkval(maxmem_offset, (int *) (&maxmem), sizeof(maxmem), "maxmem"); (void) getkval(availrmem_offset, (int *) (&availrmem), sizeof(availrmem),"availrmem");#ifdef IRIX64 si->last_pid = 0;#else (void) getkval(mpid_offset, &(si->last_pid), sizeof (si->last_pid), "mpid");#endif swapctl(SC_GETFREESWAP, &fswap); swapctl(SC_GETSWAPTOT, &tswap); memory_stats[0] = pagetok(maxmem); memory_stats[1] = pagetok(availrmem); memory_stats[2] = pagetok(freemem); memory_stats[3] = tswap / 2; memory_stats[4] = fswap / 2; /* use sysmp() to get current sysinfo usage. Can run into all kinds of problems if you try to nlist this kernel variable. */ if (sysmp(MP_SAGET, MPSA_SINFO, &sysinfo, sizeof(struct sysinfo)) == -1) { perror("sysmp"); return; } /* copy sysinfo.cpu to an array of longs, as expected by percentages() */ for (i = 0; i < CPUSTATES; i++) { cp_new[i] = sysinfo.cpu[i]; } (void) percentages (CPUSTATES, cpu_states, cp_new, cp_old, cp_diff); si->cpustates = cpu_states; si->memory = memory_stats; numcpus = sysmp(MP_NPROCS); /* add a slash to the "run" state abbreviation */ if (numcpus > 1) { state_abbrev[SRUN][3] = '/'; } return;}caddr_t get_process_info(si, sel, compare) struct system_info *si; struct process_select *sel; int (*compare)();{ register int i; register int total_procs; register int active_procs; register struct prpsinfo **prefp; register struct prpsinfo *pp; /* these are copied out of sel for speed */ int show_idle; int show_system; int show_uid; /* read all the proc structures */ getptable (pbase); /* get a pointer to the states summary array */ si->procstates = process_states; /* set up flags which define what we are going to select */ show_idle = sel->idle; show_system = sel->system; show_uid = sel->uid != -1; /* count up process states and get pointers to interesting procs */ total_procs = 0; active_procs = 0; (void) memset (process_states, 0, sizeof (process_states)); prefp = pref; for (pp = pbase, i = 0; i < nproc; pp++, i++) { /* * Place pointers to each valid proc structure in pref[]. * Process slots that are actually in use have a non-zero
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -