📄 m_aix32.c
字号:
/* * top - a top users display for Unix * * SYNOPSIS: POWER and POWER2 running AIX 3.2.5.0 * * DESCRIPTION: * This is the machine-dependent module for AIX 3.2.5.0 * It is tested on all POWER architectures. * * TERMCAP: -lcurses * * CFLAGS: -DORDER -DHAVE_GETOPT * * AUTHOR: Erik Deumens <deumens@qtp.ufl.edu> */#include <stdlib.h>#include <stdio.h>#include <fcntl.h>#include <nlist.h>#include <sys/sysinfo.h>#include <procinfo.h>#include <sys/proc.h>/*#include <sys/var.h>*/#include <pwd.h>#include "top.h"#include "machine.h"#define PROCRESS(p) (((p)->u.ui_trss + (p)->u.ui_drss)*4)#define PROCSIZE(p) (((p)->u.ui_tsize/1024+(p)->u.ui_dvm)*4)#define PROCTIME(pi) (pi->u.ui_ru.ru_utime.tv_sec + pi->u.ui_ru.ru_stime.tv_sec)/* * structure procsinfo exists in AIX 4.1 and is constructed here by combining * procinfo and userinfo which exists in AIX 3.2 also. */struct procsinfo { struct procinfo p; struct userinfo u;};/* * structure definition taken from 'monitor' by Jussi Maki (jmaki@hut.fi) */struct vmker { uint n0,n1,n2,n3,n4,n5,n6,n7,n8; uint totalmem; uint badmem; /* this is used in RS/6000 model 220 */ uint freemem; uint n12; uint numperm; /* this seems to keep other than text and data segment usage; name taken from /usr/lpp/bos/samples/vmtune.c */ uint totalvmem,freevmem; uint n15, n16, n17, n18, n19;};#define KMEM "/dev/kmem"/* Indices in the nlist array */#define X_AVENRUN 0#define X_SYSINFO 1#define X_VMKER 2#define X_PROC 3#define X_V 4static struct nlist nlst[] = { { "avenrun", 0, 0, 0, 0, 0 }, /* 0 */ { "sysinfo", 0, 0, 0, 0, 0 }, /* 1 */ { "vmker", 0, 0, 0, 0, 0 }, /* 2 */ { "proc", 0, 0, 0, 0, 0 }, /* 3 */ { "v", 0, 0, 0, 0, 0 }, /* 4 */ { NULL, 0, 0, 0, 0, 0 }};/* get_process_info returns handle. definition is here */struct handle{ struct procsinfo **next_proc; int 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 %5d%c %4d%c %-5s %6s %5.2f%% %5.2f%% %.14s%s"/* these are for detailing the process states */int process_states[9];char *procstatenames[] = { " none, ", " sleeping, ", " state2, ", " runnable, ", " idle, ", " zombie, ", " stopped, ", " running, ", " swapped, ", NULL};/* these are for detailing the cpu states */int cpu_states[4];char *cpustatenames[] = { "idle", "user", "kernel", "wait", NULL};/* these are for detailing the memory statistics */int memory_stats[7];char *memorynames[] = { "M Total. Real: ", "M, ", "M Free, ", "M Buffers. Virtual: ", "M, ", "M Free, ", NULL};#define M_TOTAL 0#define M_REAL 1#define M_REALFREE 2#define M_BUFFERS 3#define M_VIRTUAL 4#define M_VIRTFREE 5char *state_abbrev[] = { "", "sleep", "", "run", "sleep", "zomb", "stop", "run", "swap"};/* sorting orders. first is default */char *ordernames[] = { "cpu", "size", "res", "time", "pri", NULL};/* compare routines */int compare_cpu(), compare_size(), compare_res(), compare_time(), compare_prio();int (*proc_compares[])() = { compare_cpu, compare_size, compare_res, compare_time, compare_prio, NULL};/* useful externals */extern int errno;extern char *sys_errlist[];long lseek();long time();long percentages();/* useful globals */int kmem; /* file descriptor *//* offsets in kernel */static unsigned long avenrun_offset;static unsigned long sysinfo_offset;static unsigned long vmker_offset;static unsigned long proc_offset;static unsigned long v_offset;/* used for calculating cpu state percentages */static long cp_time[CPU_NTIMES];static long cp_old[CPU_NTIMES];static long cp_diff[CPU_NTIMES];/* the runqueue length is a cumulative value. keep old value */long old_runque;/* process info *//*struct var v_info;*/ /* to determine nprocs */int nprocs; /* maximum nr of procs in proctab */int ncpus; /* nr of cpus installed */int ptsize; /* size of process table in bytes */struct proc *p_proc; /* a copy of the process table */struct procsinfo *p_info; /* needed for vm and ru info */struct procinfo *p_infop; /* return array for getproc call */struct procsinfo **pref; /* processes selected for display */int pref_len; /* number of processes selected *//* needed to calculate WCPU */unsigned long curtime;/* * Initialize globals, get kernel offsets and stuff... */machine_init(statics) struct statics *statics;{ if ((kmem = open(KMEM, O_RDONLY)) == -1) { perror(KMEM); return -1; } /* get kernel symbol offsets */ if (knlist(nlst, 5, sizeof(struct nlist)) != 0) { perror("knlist"); return -1; } avenrun_offset = nlst[X_AVENRUN].n_value; sysinfo_offset = nlst[X_SYSINFO].n_value; vmker_offset = nlst[X_VMKER].n_value; proc_offset = nlst[X_PROC].n_value; v_offset = nlst[X_V].n_value; ncpus = 1; /* number of cpus, AIX 3.2 has only 1 CPU */ nprocs = PROCMASK(NPROC); ptsize = nprocs * sizeof (struct proc); p_proc = (struct proc *)malloc(ptsize); p_info = (struct procsinfo *)malloc(nprocs * sizeof (struct procsinfo)); p_infop = (struct procinfo *)malloc(nprocs * sizeof (struct procinfo)); pref = (struct procsinfo **)malloc(nprocs * sizeof (struct procsinfo *)); if (!p_proc || !p_info || !p_infop || !pref) { fprintf(stderr, "top: not enough memory\n"); return -1; } statics->procstate_names = procstatenames; statics->cpustate_names = cpustatenames; statics->memory_names = memorynames; statics->order_names = ordernames; 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);}get_system_info(si) struct system_info *si;{ int load_avg[3]; struct sysinfo s_info; struct vmker m_info; int i; double total = 0; /* get the load avarage array */ getkval(avenrun_offset, (caddr_t)load_avg, sizeof load_avg, "avenrun"); /* get the sysinfo structure */ getkval(sysinfo_offset, (caddr_t)&s_info, sizeof s_info, "sysinfo"); /* get vmker structure */ getkval(vmker_offset, (caddr_t)&m_info, sizeof m_info, "vmker"); /* convert load avarages to doubles */ for (i = 0; i < 3; i++) si->load_avg[i] = (double)load_avg[i]/65536.0; /* calculate cpu state in percentages */ for (i = 0; i < CPU_NTIMES; i++) { cp_old[i] = cp_time[i]; cp_time[i] = s_info.cpu[i]; cp_diff[i] = cp_time[i] - cp_old[i]; total += cp_diff[i]; } total = total/1000.0; /* top itself will correct this */ for (i = 0; i < CPU_NTIMES; i++) { cpu_states[i] = cp_diff[i] / total; } /* calculate memory statistics, scale 4K pages to megabytes */#define PAGE_TO_MB(a) ((a)*4/1024) memory_stats[M_TOTAL] = PAGE_TO_MB(m_info.totalmem+m_info.totalvmem); memory_stats[M_REAL] = PAGE_TO_MB(m_info.totalmem); memory_stats[M_REALFREE] = PAGE_TO_MB(m_info.freemem); memory_stats[M_BUFFERS] = PAGE_TO_MB(m_info.numperm); memory_stats[M_VIRTUAL] = PAGE_TO_MB(m_info.totalvmem); memory_stats[M_VIRTFREE] = PAGE_TO_MB(m_info.freevmem); /* runnable processes */ process_states[0] = s_info.runque - old_runque; old_runque = s_info.runque; si->cpustates = cpu_states; si->memory = memory_stats;}static struct handle handle;caddr_t get_process_info(si, sel, compare) struct system_info *si; struct process_select *sel; int (*compare)();{ int i, nproc, st; int active_procs = 0, total_procs = 0; struct procsinfo *pp, **p_pref = pref; unsigned long pctcpu; pid_t procsindex = 0; struct proc *p; si->procstates = process_states; curtime = time(0); /* get the procinfo structures of all running processes */ nproc = getproc(p_infop, nprocs, sizeof (struct procinfo)); if (nproc < 0) { perror("getproc"); quit(1); } for (i=0; i<nproc; i++) { st = getuser(&p_infop[i],sizeof(struct procinfo), &p_info[i].u,sizeof(struct userinfo)); if (st==-1) p_infop[i].pi_stat = SZOMB; memcpy (&p_info[i].p,&p_infop[i],sizeof(struct procinfo)); } /* the swapper has no cmd-line attached */ strcpy(p_info[0].u.ui_comm, "swapper"); /* get proc table */ getkval(proc_offset, (caddr_t)p_proc, ptsize, "proc"); memset(process_states, 0, sizeof process_states);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -