📄 m_aix43.c
字号:
/* * top - a top users display for Unix * * SYNOPSIS: PowerPC running AIX 4.2 or higher * * DESCRIPTION: * This is the machine-dependent module for AIX 4.2 and higher * It is currenlty only tested on PowerPC architectures. * * TERMCAP: -lcurses * * CFLAGS: -DORDER -DHAVE_GETOPT * * LIBS: -bD:0x18000000 * * AUTHOR: Joep Vesseur <joep@fwi.uva.nl> * * PATCHES: Antoine Tabary <tabary@bruyeres.cea.fr> */#include <stdlib.h>#include <stdio.h>#include <fcntl.h>#include <nlist.h>#include <sys/sysinfo.h>#include <procinfo.h>#include <sys/proc.h>#include <pwd.h>#include "top.h"#include "machine.h"#define PROCRESS(p) (((p)->pi_trss + (p)->pi_drss)*4)#define PROCSIZE(p) (((p)->pi_tsize/1024+(p)->pi_dvm)*4)#define PROCTIME(pi) (pi->pi_ru.ru_utime.tv_sec + pi->pi_ru.ru_stime.tv_sec)/* * 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 7#define Proc_format \ "%6d %-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", "", "", "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 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; getkval(v_offset, (caddr_t)&v_info, sizeof v_info, "v"); ncpus = v_info.v_ncpus; /* number of cpus */ nprocs = PROCMASK(PIDMAX); ptsize = nprocs * sizeof (struct proc); p_proc = (struct proc *)malloc(ptsize); p_info = (struct procsinfo *)malloc(nprocs * sizeof (struct procsinfo)); pref = (struct procsinfo **)malloc(nprocs * sizeof (struct procsinfo *)); if (!p_proc || !p_info || !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; int ptsize_util; 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 procsinfo structures of all running processes */ nproc = getprocs(p_info, sizeof (struct procsinfo), NULL, 0, &procsindex, nprocs); if (nproc < 0) { perror("getprocs"); quit(1); } /* the swapper has no cmd-line attached */ strcpy(p_info[0].pi_comm, "swapper"); /* get proc table */ ptsize_util = (PROCMASK(p_info[nproc-1].pi_pid)+1) * sizeof(struct proc); getkval(proc_offset, (caddr_t)p_proc, ptsize_util, "proc"); memset(process_states, 0, sizeof process_states); /* build a list of pointers to processes to show. walk through the * list of procsinfo structures instead of the proc table since the * mapping of procsinfo -> proctable is easy, the other way around * is cumbersome */ for (pp = p_info, i = 0; i < nproc; pp++, i++) { p = &p_proc[PROCMASK(pp->pi_pid)];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -