📄 m_svr5.c
字号:
/* * top - a top users display for Unix * * SYNOPSIS: For Intel based System V Release 5 (Unixware7) * * DESCRIPTION: * System V release 5 for i[3456]86 * Works for: * i586-sco-sysv5uw7 i386 SCO UNIX_SVR5 (UnixWare 7) * * LIBS: -lelf -lmas * * CFLAGS: -DHAVE_GETOPT -DORDER * * AUTHORS: Mike Hopkirk <hops@sco.com> * David Cutter <dpc@grail.com> * Andrew Herbert <andrew@werple.apana.org.au> * Robert Boucher <boucher@sofkin.ca> *//* build config * SHOW_NICE - process nice fields don't seem to be being updated so changed * default to display # of threads in use instead. * define this to display nice fields (values always 0) * #define SHOW_NICE 1 */#define _KMEMUSER#define prpsinfo psinfo#include <sys/procfs.h>#define pr_state pr_lwp.pr_state#define pr_nice pr_lwp.pr_nice#define pr_pri pr_lwp.pr_pri#define pr_onpro pr_lwp.pr_onpro#define ZOMBIE(p) ((p)->pr_nlwp == 0)#define SIZE_K(p) pagetok((p)->pr_size)#define RSS_K(p) pagetok((p)->pr_rssize)#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/param.h>#include <sys/proc.h>#include <sys/sysmacros.h>#include <vm/anon.h> #include <sys/priocntl.h>#include <sys/tspriocntl.h> #include <sys/var.h>#include "top.h"#include "machine.h"#include "utils.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 pagetok(size) ((size) * pagesz) >> LOG1024/* definitions for the index in the nlist array */#define X_AVENRUN 0#define X_V 1#define X_MPID 2static struct nlist nlst[] ={ {"avenrun"}, /* 0 */ {"v"}, /* 1 */ {"nextpid"}, /* 2 */ {NULL}};static unsigned long avenrun_offset;static unsigned long mpid_offset;static unsigned int pagesz;static void reallocproc(int n);static int maxprocs;/* 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[] =#ifdef SHOW_NICE" PID X PRI NICE SIZE RES STATE TIME CPU COMMAND";#else" PID X PRI THR SIZE RES STATE TIME CPU COMMAND";#endif/* 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 %8.4f%% %.16s"char *state_abbrev[] ={"oncpu", "run", "sleep", "stop", "idle", "zombie"};#define sZOMB 5int process_states[8];char *procstatenames[] ={ " on cpu, ", " running, ", " sleeping, ", " stopped, ", " idling ", " zombie, ", NULL};int cpu_states[CPUSTATES];char *cpustatenames[] ={"idle", "user", "kernel", "wait", NULL};/* these are for detailing the memory statistics */int memory_stats[5];char *memorynames[] ={"K phys, ", "K used, ", "K free, ", "K swapUsed, ", "K swapFree", NULL};/* these are names given to allowed sorting orders -- first is default */char *ordernames[] = {"state", "cpu", "size", "res", "time", "pid", "uid", "rpid", "ruid", NULL};/* forward definitions for comparison functions */int proc_compare();int compare_cpu();int compare_size();int compare_res();int compare_time();int compare_pid();int compare_uid();int compare_rpid();int compare_ruid();int (*proc_compares[])() = { proc_compare, compare_cpu, compare_size, compare_res, compare_time, compare_pid, compare_uid, compare_rpid, compare_ruid, NULL };static int kmem = -1;static int nproc;static int bytes;static struct prpsinfo *pbase;static struct prpsinfo **pref;static DIR *procdir;/* useful externals */extern int errno;extern char *sys_errlist[];extern char *myname;extern long percentages ();extern int check_nlist ();extern int getkval ();extern void perror ();extern void getptable ();extern void quit ();extern int nlist ();/* fwd dcls */static int kmet_init(void );static int get_cpustates(int *new);intmachine_init (struct statics *statics) { static struct var v; int i; /* fill in the statics information */ statics->procstate_names = procstatenames; statics->cpustate_names = cpustatenames; statics->memory_names = memorynames; statics->order_names = ordernames; /* 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); } v.v_proc=200; /* arbitrary default */ /* get the symbol values out of kmem */ /* NPROC Tuning parameter for max number of processes */ (void) getkval (nlst[X_V].n_value, &v, sizeof (struct var), nlst[X_V].n_name); nproc = v.v_proc; maxprocs = nproc; /* stash away certain offsets for later use */ mpid_offset = nlst[X_MPID].n_value; avenrun_offset = nlst[X_AVENRUN].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 *)); pagesz = sysconf(_SC_PAGESIZE); /* 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); } kmet_init(); /* 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]; long mem; static time_t cp_old[CPUSTATES]; static time_t cp_diff[CPUSTATES]; /* for cpu state percentages */ register int i; static long swap_total; static long swap_free; int new_states[CPUSTATES]; get_cpustates(new_states); /* convert cp_time counts to percentages */ (void) percentages (CPUSTATES, cpu_states, new_states, cp_old, cp_diff); si->last_pid = -1; /* get mpid -- process id of last process * svr5 is nextpid - next pid to be assigned (already incremented) */ (void) getkval (mpid_offset, &(si->last_pid), sizeof (si->last_pid), "nextpid"); (si->last_pid)--; /* so we shld decrement for display */ /* 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]); mem = sysconf(_SC_TOTAL_MEMORY); /* physical mem */ memory_stats[0] = pagetok (mem); mem = kmet_get_freemem(); /* free mem */ memory_stats[2] = pagetok (mem); /* mem = sysconf(_SC_GENERAL_MEMORY); */ memory_stats[1] = memory_stats[0] - memory_stats[2]; /* active */ get_swapinfo(&swap_total, &swap_free); memory_stats[3] = pagetok(swap_total - swap_free); memory_stats[4] = pagetok(swap_free); /* 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 */ /* 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; nproc = kmet_get_nproc(); /* 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 PR_ISSYS set are system * processes---these get ignored unless show_sysprocs is set. */ if ((pp->pr_state >= SONPROC && pp->pr_state <= SIDL) && (show_system || ((pp->pr_flag & PR_ISSYS) == 0))) { total_procs++; process_states[pp->pr_state]++; if ((!ZOMBIE(pp)) && (show_idle || (pp->pr_state == SRUN) || (pp->pr_state == SONPROC)) && (!show_uid || pp->pr_uid == (uid_t) sel->uid)) { *prefp++ = pp; active_procs++; } if (ZOMBIE(pp)) process_states[sZOMB]++; /* invented */ } } /* if requested, sort the "interesting" processes */ if (compare != NULL) qsort ((char *) pref, active_procs, sizeof (struct prpsinfo *), compare); /* remember active and total counts */ si->p_total = total_procs; si->P_ACTIVE = active_procs; /* pass back a handle */ handle.next_proc = pref; handle.remaining = active_procs; return ((caddr_t) & handle);}/* * cpu percentage calculation is as fm ps.c * seems to be ratio of (sys+user time used)/(elapsed time) * i.e percent of cpu utilised when on cpu */static double percent_cpu( struct prpsinfo *pp){ static time_t tim = 0L; time_t starttime; time_t ctime; time_t etime; /* if (tim == 0L) */ tim = time((time_t *) 0); starttime = pp->pr_start.tv_sec; if (pp->pr_start.tv_nsec > 500000000) starttime++; etime = (tim - starttime); ctime = pp->pr_time.tv_sec; if (pp->pr_time.tv_nsec > 500000000) ctime++; if (etime) { /* return (float)(ctime * 100) / (unsigned)etime; */ /* this was ocasionally giving vals >100 for some * unknown reason so the below normalises it */ double pct; pct = (float)(ctime * 100) / (unsigned)etime; return (pct < 100.0) ? pct : 100.00; } return 0.00;}char fmt[MAX_COLS]; /* static area where result is built */char *format_next_process ( caddr_t handle, char *(*get_userid) ()){ register struct prpsinfo *pp; struct handle *hp; register long cputime; register double pctcpu; /* find and remember the next proc structure */ hp = (struct handle *) handle; pp = *(hp->next_proc++); hp->remaining--; /* get the cpu usage and calculate the cpu percentages */ cputime = pp->pr_time.tv_sec;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -