📄 m_aux3.c
字号:
/* * top - a top users display for Unix * * SYNOPSIS: a Mac running A/UX version 3.x * * DESCRIPTION: * This is the machine-dependent module for A/UX 3.x. * == * Although AUX does not generally have a renice systemcall, it can be * implemented by tweeking kernel memory. While such a simple hack should * not be difficult to get right, USE THIS FEATURE AT YOUR OWN RISK! * To turn on setpriority emulation, add "-DIMPLEMENT_SETPRIORITY" to * the CFLAGS when prompted in the configure script. * * CFLAGS: -Dclear=clear_scr -DPRIO_PROCESS=0 * * LIBS: * * AUTHOR: Richard Henderson <rth@tamu.edu> */#include <stddef.h>#include <stdio.h>#include <string.h>#include <errno.h>#include <fcntl.h>#include <a.out.h>#include <sys/types.h>#include <sys/signal.h>#include <sys/param.h>#include <sys/proc.h>#include <sys/user.h>#include <sys/sysinfo.h>#include <sys/var.h>#include <sys/swap.h>#define FSCALE 65536.0#include "top.h"#include "machine.h"#include "loadavg.h"/*=NLIST INFO===========================================================*/#define X_V 0#define X_SYSINFO 1#define X_AVENRUN 2#define X_MAXMEM 3#define X_FREEMEM 4#define X_SWAPTAB 5#define X_AVAILRMEM 6#define X_AVAILSMEM 7static struct nlist nlst[] = { {"v"}, {"sysinfo"}, {"avenrun"}, {"maxmem"}, {"freemem"}, {"swaptab"}, {0}, /* "availrmem" */ {0}, /* "availsmem" */ {0}};static int kmem;static int mem;static struct var v;#define V_OFS (nlst[X_V].n_value)#define SYSINFO_OFS (nlst[X_SYSINFO].n_value)#define AVENRUN_OFS (nlst[X_AVENRUN].n_value)#define MAXMEM_OFS (nlst[X_MAXMEM].n_value)#define FREEMEM_OFS (nlst[X_FREEMEM].n_value)#define SWAPTAB_OFS (nlst[X_SWAPTAB].n_value)#define AVAILRMEM_OFS (nlst[X_AVAILRMEM].n_value)#define AVAILSMEM_OFS (nlst[X_AVAILSMEM].n_value)/*=SYSTEM STATE INFO====================================================*//* these are for calculating cpu state percentages */static long cp_time[NCPUSTATES];static long cp_old[NCPUSTATES];static long cp_diff[NCPUSTATES];/* these are for keeping track of the proc array */struct top_proc{ pid_t p_pid; pid_t p_pgrp; uid_t p_uid; int p_pri; int p_nice; int p_size; int p_stat; int p_flag; int p_slot; time_t p_start; time_t p_time; float p_pcpu; float p_wcpu; char p_name[COMMSIZ];};static int hash_size;static struct top_proc *ptable; /* the hash table of processes */static struct top_proc *eptable;static struct top_proc **pactive; /* list of active structures */static struct top_proc **nextactive; /* for iterating through the processes */static struct proc *preal;static struct proc *epreal;static pid_t last_pid;static struct timeval last_update;/* these are for passing data back to the mach. ind. portion */static int cpu_states[NCPUSTATES];static int process_states[8];static int memory_stats[6];/* a few useful macros... */#define blocktok(b) ((b) >> 1)#define pagetok(pg) ((pg) << (v.v_pageshift - LOG1024))#define HASH(x) ((x) * 1686629713UL % hash_size)/*=STATE IDENT STRINGS==================================================*/static char *state_abbrev[] ={ "", "sleep", "run", "zomb", "stop", "start", "cpu", "swap", NULL};static char *procstatenames[] ={ "", " sleeping, ", " running, ", " zombie, ", " stopped, ", " starting, ", " on cpu, ", " swapping, ", NULL};static char *cpustatenames[] ={ "idle", "user", "kernel", "wait", "nice", NULL};static char *memorynames[] = { "K used, ", "K free, ", "K locked Swap: ", "K used, ", "K free", NULL};static char fmt_header[] = " PID PGRP X PRI NICE SIZE STATE TIME WCPU CPU COMMAND";/*======================================================================*/intmachine_init(statics) struct statics *statics;{ /* access kernel memory */ if (#ifdef IMPLEMENT_SETPRIORITY (kmem = open("/dev/kmem", O_RDWR)) < 0 &&#endif (kmem = open("/dev/kmem", O_RDONLY)) < 0) { perror("/dev/kmem"); return -1; } if ((mem = open("/dev/mem", O_RDONLY)) < 0) { perror("/dev/mem"); return -1; } /* get the list of symbols we want to access in the kernel */ nlst[X_AVAILRMEM].n_nptr = "availrmem"; nlst[X_AVAILSMEM].n_nptr = "availsmem"; if (nlist("/unix", nlst) < 0) { fprintf(stderr, "top: nlist failed\n"); return -1; } /* make sure they were all found */ if (check_nlist(nlst) > 0) return -1; /* grab the kernel configuration information */ (void)getkval(V_OFS, (char *)&v, sizeof(v), "v"); /* allocate space for process related info */ hash_size = v.v_proc * 3 / 2; ptable = (struct top_proc *)malloc(hash_size * sizeof(struct top_proc)); pactive = (struct top_proc **)malloc(v.v_proc * sizeof(struct top_proc *)); if (!ptable || !pactive) { fprintf(stderr, "top: can't allocate sufficient memory\n"); return -1; } eptable = ptable + hash_size; { struct top_proc *p; for (p = ptable; p != eptable; ++p) p->p_pid = -1; } /* fill in the statics information */ statics->procstate_names = procstatenames; statics->cpustate_names = cpustatenames; statics->memory_names = memorynames; /* all done! */ return 0;}static struct top_proc *lookup_proc(id) pid_t id;{ struct top_proc *p; p = ptable+HASH(rp->p_pid); while (p->p_pid != rp->p_pid && p->p_pid != -1) { if (++p == eptable) p = ptable; } return p;} static voidupdate_proc_table(){ struct proc *rp; struct top_proc *p; float timediff, alpha, beta; getkval((long)v.ve_proctab, (char *)preal, sizeof(struct proc)*v.v_proc, "proc array"); /* calculate the time difference since our last proc read */ { struct timeval thistime; gettimeofday(&thistime, 0); if (last_update.tv_sec) timediff = ((thistime.tv_sec - last_update.tv_sec) + (thistime.tv_usec - last_update.tv_usec) * 1e-6); else timediff = 1e9; last_update = thistime; } /* calculate constants for the exponental average */ if (timediff < 30.0) { alpha = 0.5 * (timediff / 30.0); beta = 1.0 - alpha; } else alpha = beta = 0.5; timediff *= v.v_hz; /* mark the hash table entries as not seen */ for (p = ptable; p != eptable; ++p) p->p_stat = 0; for (rp = preal; rp != epreal; ++rp) { struct user u; if (rp->p_stat == 0) continue; else if (rp->p_stat == SZOMB || lseek(mem, rp->p_addr, 0) < 0 || read(mem, &u, sizeof(u)) != sizeof(u)) { strcpy(u.u_comm, "???"); u.u_utime = u.u_stime = u.u_start = 0; } p = lookup_proc(rp->p_pid); p->p_pgrp = rp->p_pgrp; p->p_uid = rp->p_uid; p->p_pri = rp->p_pri - PZERO; p->p_nice = rp->p_nice - NZERO; p->p_size = pagetok(rp->p_size); p->p_stat = rp->p_stat; p->p_flag = rp->p_flag; if (p->p_pid != rp->p_pid) { /* new process */ p->p_pid = rp->p_pid; p->p_slot = rp - preal; p->p_start = u.u_start; p->p_time = u.u_utime + u.u_stime; p->p_pcpu = p->p_time / timediff; p->p_wcpu = p->p_pcpu; strncpy(p->p_name, u.u_comm, sizeof(u.u_comm)); } else { time_t oldtime = p->p_time; p->p_time = u.u_utime + u.u_stime; p->p_pcpu = (p->p_time - oldtime) / timediff; p->p_wcpu = alpha * p->p_pcpu + beta * p->p_wcpu; } } for (p = ptable; p != eptable; ++p) if (p->p_stat == 0) p->p_pid = -1;}voidget_system_info(info) struct system_info *info;{ /* convert load averages */ { load_avg ar[3]; (void)getkval(AVENRUN_OFS, (char *)&ar, sizeof(ar), "avenrun"); /* convert load averages to doubles */ info->load_avg[0] = loaddouble(ar[0]); info->load_avg[1] = loaddouble(ar[1]); info->load_avg[2] = loaddouble(ar[2]); } /* get cpu time counts */ { struct sysinfo si; (void)getkval(SYSINFO_OFS, (char *)&si, sizeof(si), "sysinfo"); memcpy(cp_time, si.cpu, sizeof(cp_time)); percentages(NCPUSTATES, cpu_states, cp_time, cp_old, cp_diff); } /* get memory usage information */ { int freemem, availrmem, availsmem, maxmem; struct swaptab swaptab[MSFILES]; int i, swaptot, swapfree; (void)getkval(MAXMEM_OFS, (char *)&maxmem, sizeof(maxmem), "maxmem"); (void)getkval(FREEMEM_OFS, (char *)&freemem, sizeof(freemem), "freemem");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -