📄 m_hpux10.c
字号:
/* * top - a top users display for Unix * * SYNOPSIS: any hp9000 running hpux version 10.x * * DESCRIPTION: * This is the machine-dependent module for HPUX 10/11 that uses pstat. * It has been tested on HP/UX 10.01, 10.20, and 11.00. It is presumed * to work also on 10.10. * Idle processes are marked by being either runnable or having a %CPU * of at least 0.1%. This fraction is defined by CPU_IDLE_THRESH and * can be adjusted at compile time. * * CFLAGS: -DHAVE_GETOPT * * LIBS: * * AUTHOR: John Haxby <john_haxby@hp.com> * AUTHOR: adapted from Rich Holland <holland@synopsys.com> * AUTHOR: adapted from Kevin Schmidt <kevin@mcl.ucsb.edu> */#include <stdio.h>#include <errno.h>#include <unistd.h>#include <ctype.h>#include <signal.h>#include <nlist.h>#include <fcntl.h>#include <stdlib.h>#include <sys/types.h>#include <sys/param.h>#include <sys/pstat.h>#include <sys/dk.h>#include <sys/stat.h>#include <sys/dirent.h>#include "top.h"#include "machine.h"#include "utils.h"/* * The idle threshold (CPU_IDLE_THRESH) is an extension to the normal * idle process check. Basically, we regard a process as idle if it is * both asleep and using less that CPU_IDLE_THRESH percent cpu time. I * believe this makes the "i" option more useful, but if you don't, add * "-DCPU_IDLE_THRESH=0.0" to the CFLAGS. */#ifndef CPU_IDLE_THRESH#define CPU_IDLE_THRESH 0.1#endif# define P_RSSIZE(p) (p)->pst_rssize# define P_TSIZE(p) (p)->pst_tsize# define P_DSIZE(p) (p)->pst_dsize# define P_SSIZE(p) (p)->pst_ssize#define VMUNIX "/stand/vmunix"#define KMEM "/dev/kmem"#define MEM "/dev/mem"#ifdef DOSWAP#define SWAP "/dev/dmem"#endif/* what we consider to be process size: */#define PROCSIZE(pp) (P_TSIZE(pp) + P_DSIZE(pp) + P_SSIZE(pp))/* definitions for indices in the nlist array */#define X_MPID 0static struct nlist nlst[] = { { "mpid" }, { 0 }};/* * These definitions control the format of the per-process area */static char header[] = " TTY PID X PRI NICE SIZE RES STATE TIME CPU COMMAND";/* 0123456789.12345 -- field to fill in starts at header+6 */#define UNAME_START 15#define Proc_format \ "%8.8s %5d %-8.8s %4d %4d %5s %5s %-5s %6s %5.2f%% %s"/* process state names for the "STATE" column of the display */char *state_abbrev[] ={ "", "sleep", "run", "stop", "zomb", "trans", "start"};/* values that we stash away in _init and use in later routines */static int kmem;static struct pst_status *pst;/* these are retrieved from the OS in _init */static int nproc;static int ncpu = 0;/* these are offsets obtained via nlist and used in the get_ functions */static unsigned long mpid_offset;/* these are for calculating cpu state percentages */static long cp_time[PST_MAX_CPUSTATES];static long cp_old[PST_MAX_CPUSTATES];static long cp_diff[PST_MAX_CPUSTATES];/* these are for detailing the process states */int process_states[7];char *procstatenames[] = { "", " sleeping, ", " running, ", " stopped, ", " zombie, ", " trans, ", " starting, ", NULL};/* these are for detailing the cpu states */int cpu_states[PST_MAX_CPUSTATES];char *cpustatenames[] = { /* roll "swait" into "block" and "ssys" into "sys" */ "usr", "nice", "sys", "idle", "", "block", "\0swait", "intr", "\0ssys", NULL};/* these are for detailing the memory statistics */int memory_stats[8];char *memorynames[] = { "Real: ", "K/", "K act/tot ", "Virtual: ", "K/", "K act/tot ", "Free: ", "K", NULL};/* these are for getting the memory statistics */static int pageshift; /* log base 2 of the pagesize *//* define pagetok in terms of pageshift */#define pagetok(size) ((size) << pageshift)/* Mapping TTY major/minor numbers is done through this structure */struct ttymap { dev_t dev; char name [9];};static struct ttymap *ttynames = NULL;static int nttys = 0;static get_tty_names ();machine_init(statics)struct statics *statics;{ struct pst_static info; int i = 0; int pagesize; /* If we can get mpid from the kernel, we'll use it, otherwise */ /* we'll guess from the most recently started proces */ if ((kmem = open (KMEM, O_RDONLY)) < 0 || (nlist (VMUNIX, nlst)) < 0 || (nlst[X_MPID].n_type) == 0) mpid_offset = 0; else mpid_offset = nlst[X_MPID].n_value; if (pstat_getstatic (&info, sizeof (info), 1, 0) < 0) { perror ("pstat_getstatic"); return -1; } /* * Allocate space for the per-process structures (pst_status). To * make life easier, simply allocate enough storage to hold all the * process information at once. This won't normally be a problem * since machines with lots of processes configured will also have * lots of memory. */ nproc = info.max_proc; pst = (struct pst_status *) malloc (nproc * sizeof (struct pst_status)); if (pst == NULL) { fprintf (stderr, "out of memory\n"); return -1; } /* * Calculate pageshift -- the value needed to convert pages to Kbytes. * This will usually be 2. */ pageshift = 0; for (pagesize = info.page_size; pagesize > 1; pagesize >>= 1) pageshift += 1; pageshift -= LOG1024; /* get tty name information */ i = 0; get_tty_names ("/dev", &i); /* fill in the statics information */ statics->procstate_names = procstatenames; statics->cpustate_names = cpustatenames; statics->memory_names = memorynames; /* all done! */ return(0);}char *format_header(uname_field)char *uname_field;{ char *ptr = header + UNAME_START; while (*uname_field != '\0') *ptr++ = *uname_field++; return header;}get_system_info(si)struct system_info *si;{ static struct pst_dynamic dynamic; int i, n; long total; pstat_getdynamic (&dynamic, sizeof (dynamic), 1, 0); ncpu = dynamic.psd_proc_cnt; /* need this later */ /* Load average */ si->load_avg[0] = dynamic.psd_avg_1_min; si->load_avg[1] = dynamic.psd_avg_5_min; si->load_avg[2] = dynamic.psd_avg_15_min; /* * CPU times * to avoid space problems, we roll SWAIT (kernel semaphore block) * into BLOCK (spin lock block) and SSYS (kernel process) into SYS * (system time) Ideally, all screens would be wider :-) */ dynamic.psd_cpu_time [CP_BLOCK] += dynamic.psd_cpu_time [CP_SWAIT]; dynamic.psd_cpu_time [CP_SWAIT] = 0; dynamic.psd_cpu_time [CP_SYS] += dynamic.psd_cpu_time [CP_SSYS]; dynamic.psd_cpu_time [CP_SSYS] = 0; for (i = 0; i < PST_MAX_CPUSTATES; i++) cp_time [i] = dynamic.psd_cpu_time [i]; percentages(PST_MAX_CPUSTATES, cpu_states, cp_time, cp_old, cp_diff); si->cpustates = cpu_states; /* * VM statistics */ memory_stats[0] = -1; memory_stats[1] = pagetok (dynamic.psd_arm); memory_stats[2] = pagetok (dynamic.psd_rm); memory_stats[3] = -1; memory_stats[4] = pagetok (dynamic.psd_avm); memory_stats[5] = pagetok (dynamic.psd_vm); memory_stats[6] = -1; memory_stats[7] = pagetok (dynamic.psd_free); si->memory = memory_stats; /* * If we can get mpid from the kernel, then we will do so now. * Otherwise we'll guess at mpid from the most recently started * process time. Note that this requires us to get the pst array * now rather than in get_process_info(). We rely on * get_system_info() being called before get_system_info() for this * to work reliably. */ for (i = 0; i < nproc; i++) pst[i].pst_pid = -1; n = pstat_getproc (pst, sizeof (*pst), nproc, 0); if (kmem >= 0 && mpid_offset > 0) (void) getkval(mpid_offset, &(si->last_pid), sizeof(si->last_pid), "mpid"); else { static int last_start_time = 0; int pid = 0; for (i = 0; i < n; i++) { if (last_start_time <= pst[i].pst_start) { last_start_time = pst[i].pst_start; if (pid <= pst[i].pst_pid) pid = pst[i].pst_pid; } } if (pid != 0) si->last_pid = pid; }}caddr_t get_process_info(si, sel, compare)struct system_info *si;struct process_select *sel;int (*compare)();{ static int handle; int i, active, total; /* * Eliminate unwanted processes * and tot up all the wanted processes by state */ for (i = 0; i < sizeof (process_states)/sizeof (process_states[0]); i++) process_states [i] = 0; for (total = 0, active = 0, i = 0; pst[i].pst_pid >= 0; i++) { int state = pst[i].pst_stat; process_states [state] += 1; total += 1; if (!sel->system && (pst[i].pst_flag & PS_SYS)) { pst[i].pst_stat = -1; continue; } /* * If we are eliminating idle processes, then a process is regarded * as idle if it is in a short term sleep and not using much * CPU, or stopped, or simple dead. */ if (!sel->idle
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -