📄 m_sco5.c
字号:
/* * top - a top users display for Unix * * SYNOPSIS: SCO UNIX OpenServer5 * * DESCRIPTION: * This is the machine-dependent module for SCO OpenServer5. * Originally written for BSD4.3 system by Christos Zoulas. * Modified to m_sco.c (3.2v4.2) by Gregory Shilin <shilin@onyx.co.il> * Modified to m_sco5.c (3.2v5.*) by Mike Hopkirk <hops@sco.com> * Works for: * SCO UNIX 3.2v5.* * * CFLAGS: -DHAVE_GETOPT -DORDER * * AUTHOR: Mike Hopkirk (hops@sco.com) * hops 10-Jul-98 - added sort fields * 17-Jul-98 - add philiph's chopped cmd string support * (define NO_COMMAND_ARGS to enable ) * 09-Dec-98 - provide RSS calculation * 15-Mar-2000 - Fix broken lines and cleanup sysinfo access w macros */#include <sys/types.h>#include <sys/param.h>#include <stdio.h>#include <unistd.h>#include <fcntl.h>#include <nlist.h>#include <math.h>#include <signal.h>#include <string.h>#include <sys/dir.h>#include <sys/immu.h>#include <sys/region.h>#include <sys/proc.h>#include <sys/user.h>#include <sys/sysinfo.h>#include <sys/systm.h>#include <sys/sysmacros.h>#include <sys/var.h>#include <sys/sysi86.h>#include "top.h"#include "machine.h"#include "utils.h"#include "loadavg.h"/*typedef unsigned long ulong;typedef unsigned int uint;typedef unsigned short ushort;*/typedef unsigned char uchar;#define VMUNIX "/unix"#define KMEM "/dev/kmem"#define MEM "/dev/mem"#define SI_ACTIVE(p) p->p_active#define SI_TOTAL(p) p->p_total/* get_process_info passes back a handle. This is what it looks like: */struct handle { struct proc **next_proc; /* points to next valid proc pointer */ int remaining; /* number of pointers remaining */};/* define what weighted cpu is */#define weighted_cpu(pct, pp) ((pp)->p_time == 0 ? 0.0 : \ ((pct) / (1.0 - exp((pp)->p_time * logcpu))))#define bytetok(bytes) ((bytes) >> 10)/* what we consider to be process size: */#define PROCSIZE(up) bytetok(ctob((up)->u_tsize + (up)->u_dsize+(up)->u_ssize))/* definitions for indices in the nlist array */#define X_V 0 /* System configuration information */#define X_PROC 1 /* process tables */#define X_FREEMEM 2 /* current free memory */#define X_AVAILRMEM 3 /* available resident (not swappable) mem in pages*/#define X_AVAILSMEM 4 /* available swappable memory in pages */#define X_MAXMEM 5 /* maximum available free memory in clicks */#define X_PHYSMEM 6 /* physical memory in clicks */#define X_NSWAP 7 /* size of swap space in blocks */#define X_HZ 8 /* ticks/second of the clock */#define X_MPID 9 /* last process id */#define X_SYSINFO 10 /* system information (cpu states) */#define X_CUR_CPU 11static struct nlist nlst[] = { { "v" }, /* 0 */ { "proc" }, /* 1 */ { "freemem" }, /* 2 */ { "availrmem" }, /* 3 */ { "availsmem" }, /* 4 */ { "maxmem" }, /* 5 */ { "physmem" }, /* 6 */ { "nswap" }, /* 7 */ { "Hz" }, /* 8 */ { "mpid" }, /* 9 */ { "sysinfo" }, /* 10 */ { "cur_cpu" }, /* 11 */ { NULL }};/* * These definitions control the format of the per-process area */static char header[] = " PID X PRI NICE SIZE RES STATE TIME COMMAND";/* 0123456 -- field to fill in starts at header+6 */#define UNAME_START 6#define Proc_format \ "%5d %-8.8s %3d %4d %5s %5dK %-5s %6s %.28s"static int kmem, mem;static double logcpu;/* these are retrieved from the kernel in _init */static int Hz;static struct var v;static ulong proca;static load_avg cur_cpu;/* these are for detailing the process states */int process_states[8];char *procstatenames[] = { "", " sleeping, ", " running, ", " zombie, ", " stopped, ", " created, ", " onproc, ", " xswapped, ", NULL};/* process state names for the "STATE" column of the display */char *state_abbrev[] = { "", "sleep", "run", "zomb", "stop", "create", "onpr", "swap"};/* these are names given to allowed sorting orders -- first is default */char *ordernames[]={"state", "cpu", "size", /*"res",*/ "time", NULL}; /*hops*//* these are for calculating cpu state percentages */#define CPUSTATES 5 /* definition from struct sysinfo */static time_t cp_time[CPUSTATES];static time_t cp_old[CPUSTATES];static time_t cp_diff[CPUSTATES];/* these are for detailing the cpu states */int cpu_states[CPUSTATES];char *cpustatenames[] = { "idle", "user", "system", "wait", "sxbrk", NULL};/* these are for detailing the memory statistics */int memory_stats[6];char *memorynames[] = { "K phys, ", "K max, ", "K free, ", "K locked, ", "K unlocked, ", "K swap,", NULL};/* these are for keeping track of the proc array */static int bytes;static int pref_len;static struct proc *pbase;static struct proc **pref;/* useful externals */extern int errno;extern char *sys_errlist[];long time();long percentages();machine_init(statics)struct statics *statics;{ulong ptr; if ((kmem = open(KMEM, O_RDONLY)) == -1) { perror(KMEM); return -1; } if ((mem = open(MEM, O_RDONLY)) == -1) { perror(MEM); return -1; } /* get the list of symbols we want to access in the kernel */ if (nlist(VMUNIX, nlst) == -1) { fprintf(stderr, "top: nlist failed\n"); return -1; } /* make sure they were all found */ /*ZZ if (check_nlist(nlst) > 0) return -1; */ proca = nlst[X_PROC].n_value; /* get the symbol values out of kmem */ (void) getkval(nlst[X_CUR_CPU].n_value, (int *)(&cur_cpu), sizeof(cur_cpu), nlst[X_CUR_CPU].n_name); (void) getkval(nlst[X_HZ].n_value, (int *)(&Hz), sizeof(Hz), nlst[X_HZ].n_name); (void) getkval(nlst[X_V].n_value, (int *)(&v), sizeof(v), nlst[X_V].n_name); /* this is used in calculating WCPU -- calculate it ahead of time */ logcpu = log(fabs(loaddouble(cur_cpu))); /* allocate space for proc structure array and array of pointers */ bytes = v.v_proc * sizeof(struct proc); pbase = (struct proc *)malloc(bytes); pref = (struct proc **)malloc(v.v_proc * sizeof(struct proc *)); if (pbase == (struct proc *)NULL || pref == (struct proc **)NULL) { fprintf(stderr, "top: cannot allocate sufficient memory\n"); return -1; } /* fill in the statics information */ statics->procstate_names = procstatenames; statics->cpustate_names = cpustatenames; statics->memory_names = memorynames; statics->order_names = ordernames ; /* hops */ 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);}/* philiph - get run ave fm /dev/table info */static inttab_avenrun(double runave[]){ FILE *fp = fopen("/dev/table/avenrun", "r"); int i; for (i=0; i<3; i++) runave[i] = -1.0; if (fp==NULL) return -1; else { short rawave[3]; if (fread(rawave, sizeof(short), 3, fp) !=3 ) { fclose(fp); return -1; } else { int i; for (i=0; i<3; i++) runave[i] = (double) (rawave[i] / 256.0); fclose(fp); return 0; } }}struct pregion *get_pregion(void *ptr){ static struct pregion preg; long addr = (long)ptr; (void) getkval(addr , (struct pregion *)(&preg), sizeof(struct pregion), "pregion" ); return &preg;}struct region *get_region(void *ptr){ static struct region reg; long addr = (long)ptr; (void) getkval( addr , (struct region *)(®), sizeof(struct region), "region" ); return ®}static unsigned char shareable[RT_VM86 + 1]; /* 1 if shareable *//* * sum private referenced pages, * treat shared pages depending on value of TREAT_SHARABLE_PAGES macro * undefined : ignore (don't account for - default) * 1: divide among # of references * 2: accumulate as if private *//* #define TREAT_SHAREABLE_PAGES 1 */static longproc_residentsize(struct proc *pp){ struct pregion *prp; struct region *rp; long rtot = 0; long stot = 0; long s1tot = 0; /* init shareable region array */ if (shareable[RT_STEXT] == 0 ) shareable[RT_STEXT] = shareable[RT_SHMEM] = shareable[RT_MAPFILE] = 1 ; prp = pp->p_region; if ( prp == 0) return 0; for( ; prp && (prp = get_pregion((void *)(prp))) && prp->p_reg && (rp = get_region((void*)(prp->p_reg))); prp = prp->p_next) { if (shareable[rp->r_type] ) /* account for shared pgs separately */ { stot += (rp->r_nvalid / rp->r_refcnt); s1tot += rp->r_nvalid; } else rtot += rp->r_nvalid; }#if defined(TREAT_SHAREABLE_PAGES) && TREAT_SHAREABLE_PAGES == 1 rtot += stot; /* accumulate and spread over users */#endif#if defined(TREAT_SHAREABLE_PAGES) && TREAT_SHAREABLE_PAGES == 1 rtot += s1tot; /* accumulate as if private */#endif return rtot * NBPP/1024; ;}get_system_info(si)struct system_info *si;{long total; /* get process id of the last process */ (void) getkval(nlst[X_MPID].n_value, &(si->last_pid), sizeof(si->last_pid), nlst[X_MPID].n_name); /* get the cp_time array */ (void) getkval(nlst[X_SYSINFO].n_value, (int *)cp_time, sizeof(cp_time), nlst[X_SYSINFO].n_name); /* convert cp_time counts to persentages */ total = percentages(CPUSTATES, cpu_states, cp_time, cp_old, cp_diff); /* sum memory statistics */ (void) getkval(nlst[X_PHYSMEM].n_value, &memory_stats[0], sizeof(memory_stats[0]), nlst[X_PHYSMEM].n_name); (void) getkval(nlst[X_MAXMEM].n_value, &memory_stats[1], sizeof(memory_stats[1]), nlst[X_MAXMEM].n_name); (void) getkval(nlst[X_FREEMEM].n_value, &memory_stats[2], sizeof(memory_stats[2]), nlst[X_FREEMEM].n_name); (void) getkval(nlst[X_AVAILRMEM].n_value, &memory_stats[3], sizeof(memory_stats[3]), nlst[X_AVAILRMEM].n_name); (void) getkval(nlst[X_AVAILSMEM].n_value, &memory_stats[4], sizeof(memory_stats[4]), nlst[X_AVAILSMEM].n_name); (void) getkval(nlst[X_NSWAP].n_value, &memory_stats[5], sizeof(memory_stats[5]), nlst[X_NSWAP].n_name); memory_stats[0] = bytetok(ctob(memory_stats[0])); /* clicks -> bytes */ memory_stats[1] = bytetok(ctob(memory_stats[1])); /* clicks -> bytes */ memory_stats[2] = bytetok(ctob(memory_stats[2])); /* clicks -> bytes */ memory_stats[3] = bytetok(memory_stats[3] * NBPP); /* # bytes per page */ memory_stats[4] = bytetok(memory_stats[4] * NBPP); /* # bytes per page */ memory_stats[5] = bytetok(memory_stats[5] * NBPSCTR);/* # bytes per sector */ /* set arrays and strings */ si->cpustates = cpu_states; si->memory = memory_stats; tab_avenrun(si->load_avg); /* philiph */}static struct handle handle;caddr_t get_process_info(si, sel, compare) struct system_info *si; struct process_select *sel; int (*compare)();{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -