⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 m_ftx.c

📁 查看系统硬件和内存资源使用情况;以及各个进程的使用情况
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * top - a top users display for Unix * * SYNOPSIS:  For FTX based System V Release 4 * * DESCRIPTION: *      System V release 4.0.x for FTX (FTX 2.3 and greater) * * LIBS:  -lelf * * AUTHORS:  Andrew Herbert     <andrew@werple.apana.org.au> *           Robert Boucher     <boucher@sofkin.ca> *           Steve Scherf	<scherf@swdc.stratus.com> */#include <stdio.h>#include <fcntl.h>#include <unistd.h>#include <stdlib.h>#include <errno.h>#include <dirent.h>#include <nlist.h>#include <string.h>#include <sys/types.h>#include <sys/param.h>#include <sys/procfs.h>#include <sys/sysmacros.h>#include <sys/sysinfo.h>#include <sys/vmmeter.h>#include <vm/anon.h>#include <sys/priocntl.h>#include <sys/rtpriocntl.h>#include <sys/tspriocntl.h>#include <sys/procset.h>#include <sys/var.h>#include <sys/tuneable.h>#include <sys/fs/rf_acct.h>#include <sys/sar.h>#include <sys/ftx/dcm.h>#include "top.h"#include "machine.h"#define UNIX "/unix"#define KMEM "/dev/kmem"#define PROCFS "/proc"#define SAR "/dev/sar"#define CPUSTATES	5#ifndef PRIO_MAX#define PRIO_MAX	20#endif#ifndef PRIO_MIN#define PRIO_MIN	-20#endif#ifndef FSCALE#define FSHIFT  8		/* bits to right of fixed binary point */#define FSCALE  (1<<FSHIFT)#endif#define loaddouble(x) ((double)(x) / FSCALE)#define pagetok(size) ctob(size) >> LOG1024#define PRTOMS(pp) \	((pp)->pr_time.tv_sec * 1000) + ((pp)->pr_time.tv_nsec / 1000000)/* definitions for the index in the nlist array */#define X_AVENRUN	0#define X_MPID		1#define X_V		2#define X_NPROC		3#define X_ANONINFO	4#define X_TOTAL		5static struct nlist nlst[] ={  {"avenrun"},			/* 0 */  {"mpid"},			/* 1 */  {"v"},			/* 2 */  {"nproc"},			/* 3 */  {"anoninfo"},			/* 4 */  {"total"},			/* 5 */  {NULL}};static unsigned long avenrun_offset;static unsigned long mpid_offset;static unsigned long nproc_offset;static unsigned long anoninfo_offset;static unsigned long total_offset;/* get_process_info passes back a handle.  This is what it looks like: */struct handle  {    struct prpsinfo **next_proc;/* points to next valid proc pointer */    int remaining;		/* number of pointers remaining */  };#define MAXTIMEHIST	12#define HASHSZ		512	/* This must be a power of 2. */#define HASHMASK	(HASHSZ - 1)#define TF_USED		0x01#define TF_NEWPROC	0x02#define TD_HASH(pid) \	(timedata_t *)(&hash[(pid) & HASHMASK])typedef struct hash {	struct timedata *hnext;	struct timedata *hlast;} hash_t;/* data for CPU and WCPU fields */typedef struct timedata {	struct timedata *hnext;	struct timedata *hlast;	struct timedata *lnext;	struct timedata *llast;	pid_t pid;	char index;	char cnt;	char flags;	long hist[MAXTIMEHIST];	long time;	long ltime;} timedata_t;/* *  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%6dK %4dK %-5s%4d:%02d %5.2f%% %5.2f%% %.16s"char *state_abbrev[] ={"", "sleep", "run", "zombie", "stop", "start", "cpu", "swap"};int process_states[8];char *procstatenames[] ={  "", " sleeping, ", " running, ", " zombie, ", " stopped, ",  " starting, ", " on cpu, ", " swapped, ",  NULL};int cpu_states[CPUSTATES];char *cpustatenames[] ={"idle", "user", "kernel", "wait", "swap", NULL};/* these are for detailing the memory statistics */int memory_stats[5];char *memorynames[] ={"K real, ", "K active, ", "K free, ", "K swap, ", "K free swap", NULL};static int kmem;static int sar;static int initted;static int nproc;static int bytes;static struct prpsinfo *pbase;static struct prpsinfo **pref;static DIR *procdir;static char cpu_state[MAX_LOG_CPU];static struct sysinfo cpu_sysinfo[MAX_LOG_CPU];static sar_percpu_args_t spa;static timedata_t timedata;static long total_time;static double total_cpu;static hash_t hash[HASHSZ];/* useful externals */extern int errno;extern char *sys_errlist[];extern char *myname;extern long percentages ();extern int check_nlist ();extern int getkval ();extern void perror ();extern void getptable ();extern void quit ();extern int nlist ();/* Prototypes. */void getsysinfo(struct sysinfo *);void add_time(struct prpsinfo *);void get_cpu(struct prpsinfo *, double *, double *);void clean_timedata(void);timedata_t *get_timedata(struct prpsinfo *);intmachine_init (struct statics *statics)  {    int i;    static struct var v;    /* fill in the statics information */    statics->procstate_names = procstatenames;    statics->cpustate_names = cpustatenames;    statics->memory_names = memorynames;    /* get the list of symbols we want to access in the kernel */    if (nlist (UNIX, nlst))      {	(void) fprintf (stderr, "Unable to nlist %s\n", UNIX);	return (-1);      }    /* make sure they were all found */    if (check_nlist (nlst) > 0)      return (-1);    /* open kernel memory */    if ((kmem = open (KMEM, O_RDONLY)) == -1)      {	perror (KMEM);	return (-1);      }    /* Open the sar driver device node. */    if ((sar = open(SAR, O_RDONLY)) == -1)      {        perror (SAR);        return (-1);      }    /* get the symbol values out of kmem */    /* NPROC Tuning parameter for max number of processes */    (void) getkval (nlst[X_V].n_value, &v, sizeof (struct var), nlst[X_V].n_name);    nproc = v.v_proc;    /* stash away certain offsets for later use */    mpid_offset = nlst[X_MPID].n_value;    nproc_offset = nlst[X_NPROC].n_value;    avenrun_offset = nlst[X_AVENRUN].n_value;    anoninfo_offset = nlst[X_ANONINFO].n_value;    total_offset = nlst[X_TOTAL].n_value;    /* allocate space for proc structure array and array of pointers */    bytes = nproc * sizeof (struct prpsinfo);    pbase = (struct prpsinfo *) malloc (bytes);    pref = (struct prpsinfo **) malloc (nproc * sizeof (struct prpsinfo *));    /* Just in case ... */    if (pbase == (struct prpsinfo *) NULL || pref == (struct prpsinfo **) NULL)      {	(void) fprintf (stderr, "%s: can't allocate sufficient memory\n", myname);	return (-1);      }    if (!(procdir = opendir (PROCFS)))      {	(void) fprintf (stderr, "Unable to open %s\n", PROCFS);	return (-1);      }    if (chdir (PROCFS))      {				/* handy for later on when we're reading it */	(void) fprintf (stderr, "Unable to chdir to %s\n", PROCFS);	return (-1);      }    /* Set up the pointers to the sysinfo data area. */    spa.uvcp = (caddr_t) &cpu_state[0];    spa.uvsp = (caddr_t) &cpu_sysinfo[0];    timedata.lnext = &timedata;    timedata.llast = &timedata;    for (i = 0; i < HASHSZ; i++) {      hash[i].hnext = (timedata_t *)&hash[i];      hash[i].hlast = (timedata_t *)&hash[i];    }    /* all done! */    return (0);  }char *format_header (char *uname_field){  register char *ptr;  ptr = header + UNAME_START;  while (*uname_field != '\0')    *ptr++ = *uname_field++;  return (header);}voidget_system_info (struct system_info *si){  long avenrun[3];  struct sysinfo sysinfo;  struct vmtotal total;  struct anoninfo anoninfo;  static time_t cp_old[CPUSTATES];  static time_t cp_diff[CPUSTATES];	/* for cpu state percentages */  register int i;  getsysinfo(&sysinfo);  /* convert cp_time counts to percentages */  (void) percentages (CPUSTATES, cpu_states, sysinfo.cpu, cp_old, cp_diff);  /* Find total CPU utilization, as a fraction of 1. */  total_cpu = (cpu_states[CPU_USER] + cpu_states[CPU_KERNEL]) / 1000.0;  /* get mpid -- process id of last process */  (void) getkval (mpid_offset, &(si->last_pid), sizeof (si->last_pid),		  "mpid");  /* get load average array */  (void) getkval (avenrun_offset, (int *) avenrun, sizeof (avenrun), "avenrun");  /* convert load averages to doubles */  for (i = 0; i < 3; i++)    si->load_avg[i] = loaddouble (avenrun[i]);  /* get total -- systemwide main memory usage structure */  (void) getkval (total_offset, (int *) (&total), sizeof (total), "total");  /* convert memory stats to Kbytes */  memory_stats[0] = pagetok (total.t_rm);  memory_stats[1] = pagetok (total.t_arm);  memory_stats[2] = pagetok (total.t_free);  (void) getkval (anoninfo_offset, (int *) (&anoninfo), sizeof (anoninfo),		  "anoninfo");  memory_stats[3] = pagetok (anoninfo.ani_max - anoninfo.ani_free);  memory_stats[4] = pagetok (anoninfo.ani_max - anoninfo.ani_resv);  /* set arrays and strings */  si->cpustates = cpu_states;  si->memory = memory_stats;}static struct handle handle;caddr_tget_process_info (		   struct system_info *si,		   struct process_select *sel,		   int (*compare) ()){  register int i;  register int total_procs;  register int active_procs;  register struct prpsinfo **prefp;  register struct prpsinfo *pp;  /* these are copied out of sel for speed */  int show_idle;  int show_system;  int show_uid;  /* Get current number of processes */  (void) getkval (nproc_offset, (int *) (&nproc), sizeof (nproc), "nproc");  /* read all the proc structures */  getptable (pbase);  /* get a pointer to the states summary array */  si->procstates = process_states;  /* set up flags which define what we are going to select */  show_idle = sel->idle;  show_system = sel->system;  show_uid = sel->uid != -1;  /* count up process states and get pointers to interesting procs */  total_procs = 0;  active_procs = 0;  total_time = 0;  (void) memset (process_states, 0, sizeof (process_states));  prefp = pref;  clean_timedata();  for (pp = pbase, i = 0; i < nproc; pp++, i++)    {      /*	 *  Place pointers to each valid proc structure in pref[].	 *  Process slots that are actually in use have a non-zero	 *  status field.  Processes with SSYS set are system	 *  processes---these get ignored unless show_sysprocs is set.	 */      if (pp->pr_state != 0 &&	  (show_system || ((pp->pr_flag & SSYS) == 0)))	{	  total_procs++;	  process_states[pp->pr_state]++;	  if ((!pp->pr_zomb) &&	      (show_idle || (pp->pr_state == SRUN) || (pp->pr_state == SONPROC)) &&	      (!show_uid || pp->pr_uid == (uid_t) sel->uid))	    {	      *prefp++ = pp;	      active_procs++;	    }	}      if (pp->pr_state != 0)        add_time(pp);    }  /* Note that we've run this at least once. */  initted++;  /* if requested, sort the "interesting" processes */  if (compare != NULL)      qsort ((char *) pref, active_procs, sizeof (struct prpsinfo *), compare);  /* remember active and total counts */  si->p_total = total_procs;  si->p_active = active_procs;  /* pass back a handle */  handle.next_proc = pref;  handle.remaining = active_procs;  return ((caddr_t) & handle);}char fmt[128];			/* static area where result is built */char *format_next_process (		      caddr_t handle,		      char *(*get_userid) ()){  register struct prpsinfo *pp;  struct handle *hp;  register long cputime;  double pctcpu;  double pctwcpu;  /* find and remember the next proc structure */  hp = (struct handle *) handle;  pp = *(hp->next_proc++);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -