📄 m_ncr3000.c
字号:
/* * top - a top users display for Unix * * SYNOPSIS: For NCR 3000 series systems Release 2.00.02 and above - * works on 2.03.00 and earlier (and probably later) OS releases. * (Intel based System V Release 4) * * DESCRIPTION: * System V release 4 for NCR 3000 series OS Rel 02.03.00 and above * * LIBS: -lelf * * AUTHORS: Andrew Herbert <andrew@werple.apana.org.au> * Robert Boucher <boucher@sofkin.ca> * Jeff Janvrin <jeff.janvrin@columbiasc.ncr.com> * did the port to statfs (2.03) */#include "top.h"#include "machine.h"#include "utils.h"#include <stdio.h>#include <fcntl.h>#include <unistd.h>#include <stdlib.h>#include <errno.h>#include <dirent.h>#include <nlist.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/param.h>#include <sys/procfs.h>#include <sys/sysinfo.h>#include <sys/sysmacros.h>#include <sys/vmmeter.h>#include <vm/anon.h>#include <sys/priocntl.h>#include <sys/rtpriocntl.h>#include <sys/tspriocntl.h>#include <sys/procset.h>#include <sys/var.h>#define UNIX "/stand/unix"#define KMEM "/dev/kmem"#define PROCFS "/proc"#define CPUSTATES 5#ifndef PRIO_MAX#define PRIO_MAX 20#endif#ifndef PRIO_MIN#define PRIO_MIN -20#endif#ifndef FSCALE#define FSHIFT 8 /* bits to right of fixed binary point */#define FSCALE (1<<FSHIFT)#endif#define loaddouble(x) ((double)(x) / FSCALE)#define percent_cpu(x) ((double)(x)->pr_cpu / FSCALE)#define weighted_cpu(pct, pp) ( ((pp)->pr_time.tv_sec) == 0 ? 0.0 : \ ((pp)->pr_cpu) / ((pp)->pr_time.tv_sec) )#define pagetok(size) ctob(size) >> LOG1024/* definitions for the index in the nlist array */#define X_AVENRUN 0#define X_MPID 1#define X_V 2#define X_NPROC 3#define X_ANONINFO 4#define X_TOTAL 5#define X_SYSINFO 6static struct nlist nlst[] ={{"avenrun"}, /* 0 */{"mpid"}, /* 1 */{"v"}, /* 2 */{"nproc"}, /* 3 */{"anoninfo"}, /* 4 */{"total"}, /* 5 */{"sysinfo"}, /* 6 */{NULL}};static unsigned long avenrun_offset;static unsigned long mpid_offset;static unsigned long nproc_offset;static unsigned long anoninfo_offset;static unsigned long total_offset;static unsigned long sysinfo_offset;/* 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 */ };/* * 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 %3d.0%% %5.2f%% %.16s"char *state_abbrev[] ={"", "sleep", "run", "zombie", "stop", "start", "cpu", "swap"};int process_states[8];char *procstatenames[] ={ "", " sleeping, ", " running, ", " zombie, ", " stopped, ", " starting, ", " on cpu, ", " swapped, ", NULL};int cpu_states[CPUSTATES];char *cpustatenames[] ={"idle", "user", "kernel", "wait", "swap", NULL};/* these are for detailing the memory statistics */int memory_stats[5];char *memorynames[] ={"K real, ", "K active, ", "K free, ", "K swap, ", "K free swap", NULL};static int kmem = -1;static int nproc;static int bytes;static int use_stats = 0;static struct prpsinfo *pbase;static struct prpsinfo **pref;static DIR *procdir;/* useful externals */extern int errno;extern char *sys_errlist[];extern char *myname;extern int check_nlist ();extern int getkval ();extern void perror ();extern void getptable ();extern void quit ();extern int nlist ();intmachine_init (struct statics *statics) { static struct var v; /* fill in the statics information */ statics->procstate_names = procstatenames; statics->cpustate_names = cpustatenames; statics->memory_names = memorynames; /* get the list of symbols we want to access in the kernel */ if (nlist (UNIX, nlst)) { (void) fprintf (stderr, "Unable to nlist %s\n", UNIX); return (-1); } /* make sure they were all found */ if (check_nlist (nlst) > 0) return (-1); /* open kernel memory */ if ((kmem = open (KMEM, O_RDONLY)) == -1) { perror (KMEM); return (-1); } /* get the symbol values out of kmem */ /* NPROC Tuning parameter for max number of processes */ (void) getkval (nlst[X_V].n_value, (int *) &v, sizeof (struct var), nlst[X_V].n_name); nproc = v.v_proc; /* stash away certain offsets for later use */ mpid_offset = nlst[X_MPID].n_value; nproc_offset = nlst[X_NPROC].n_value; avenrun_offset = nlst[X_AVENRUN].n_value; anoninfo_offset = nlst[X_ANONINFO].n_value; total_offset = nlst[X_TOTAL].n_value;/* JJ this may need to be changed */ sysinfo_offset = nlst[X_SYSINFO].n_value; /* 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 *)); /* Just in case ... */ if (pbase == (struct prpsinfo *) NULL || pref == (struct prpsinfo **) NULL) { (void) fprintf (stderr, "%s: can't allocate sufficient memory\n", myname); return (-1); } if (!(procdir = opendir (PROCFS))) { (void) fprintf (stderr, "Unable to open %s\n", PROCFS); return (-1); } if (chdir (PROCFS)) { /* handy for later on when we're reading it */ (void) fprintf (stderr, "Unable to chdir to %s\n", PROCFS); return (-1); } /* all done! */ return (0); }char *format_header (char *uname_field){ register char *ptr; ptr = header + UNAME_START; while (*uname_field != '\0') *ptr++ = *uname_field++; return (header);}voidget_system_info (struct system_info *si){ long avenrun[3]; struct sysinfo sysinfo; static struct sysinfo *mpinfo = NULL; /* array, per-processor sysinfo structures. */ struct vmtotal total; struct anoninfo anoninfo; static time_t cp_old[CPUSTATES]; static time_t cp_diff[CPUSTATES]; /* for cpu state percentages */ static int num_cpus; static int fd_cpu = 0; register int i; if ( use_stats == 1) { if ( fd_cpu == 0 ) { if ((fd_cpu = open("/stats/cpuinfo", O_RDONLY)) == -1) { (void) fprintf (stderr, "%s: Open of /stats/cpuinfo failed\n", myname); quit(2); } if (read(fd_cpu, &num_cpus, sizeof(int)) != sizeof(int)) { (void) fprintf (stderr, "%s: Read of /stats/cpuinfo failed\n", myname); quit(2); } close(fd_cpu); } if (mpinfo == NULL) { mpinfo = (struct sysinfo *)calloc(num_cpus, sizeof(mpinfo[0])); if (mpinfo == NULL) { (void) fprintf (stderr, "%s: can't allocate space for per-processor sysinfos\n", myname); quit(12); } } /* Read the per cpu sysinfo structures into mpinfo struct. */ read_sysinfos(num_cpus, mpinfo); /* Add up all of the percpu sysinfos to get global sysinfo */ sysinfo_data(num_cpus, &sysinfo, mpinfo); } else { (void) getkval (sysinfo_offset, &sysinfo, sizeof (struct sysinfo), "sysinfo"); } /* convert cp_time counts to percentages */ (void) percentages (CPUSTATES, cpu_states, sysinfo.cpu, cp_old, cp_diff); /* get mpid -- process id of last process */ (void) getkval (mpid_offset, &(si->last_pid), sizeof (si->last_pid), "mpid"); /* get load average array */ (void) getkval (avenrun_offset, (int *) avenrun, sizeof (avenrun), "avenrun"); /* convert load averages to doubles */ for (i = 0; i < 3; i++) si->load_avg[i] = loaddouble (avenrun[i]); /* get total -- systemwide main memory usage structure */ (void) getkval (total_offset, (int *) (&total), sizeof (total), "total"); /* convert memory stats to Kbytes */ memory_stats[0] = pagetok (total.t_rm); memory_stats[1] = pagetok (total.t_arm); memory_stats[2] = pagetok (total.t_free); (void) getkval (anoninfo_offset, (int *) (&anoninfo), sizeof (anoninfo), "anoninfo"); memory_stats[3] = pagetok (anoninfo.ani_max - anoninfo.ani_free); memory_stats[4] = pagetok (anoninfo.ani_max - anoninfo.ani_resv); /* set arrays and strings */ si->cpustates = cpu_states; si->memory = memory_stats;}static struct handle handle;caddr_tget_process_info ( 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; /* Get current number of processes */ (void) getkval (nproc_offset, (int *) (&nproc), sizeof (nproc), "nproc"); /* 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 * status field. Processes with SSYS set are system * processes---these get ignored unless show_sysprocs is set. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -