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

📄 machine.c

📁 Ho Chi Minh City University of Technology Computer Science Department Distributed Computing E
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * top - a top users display for Unix * * SYNOPSIS:  Any Sun running SunOS 5.x (Solaris 2.x) * * DESCRIPTION: * This is the machine-dependent module for SunOS 5.x (Solaris 2). * There is some support for MP architectures. * This makes top work on the following systems: *         SunOS 5.0 (not tested) *         SunOS 5.1 *         SunOS 5.2 *         SunOS 5.3 *         SunOS 5.4 *         SunOS 5.5 *         SunOS 5.6 *         SunOS 5.7 (beta) * *     Tested on a SPARCclassic with SunOS 5.1, using gcc-2.3.3, and *     SPARCsystem 600 with SunOS 5.2, using Sun C * * LIBS: -lelf -lkvm -lkstat * * CFLAGS: -DHAVE_GETOPT -DORDER -DHAVE_STRERROR * * * AUTHORS:      Torsten Kasch 		<torsten@techfak.uni-bielefeld.de> *               Robert Boucher		<boucher@sofkin.ca> * CONTRIBUTORS: Marc Cohen 		<marc@aai.com> *               Charles Hedrick 	<hedrick@geneva.rutgers.edu> *	         William L. Jones 	<jones@chpc> *               Petri Kutvonen         <kutvonen@cs.helsinki.fi> *	         Casper Dik             <casper.dik@sun.com> *               Tim Pugh               <tpugh@oce.orst.edu> */#define _KMEMUSER#if (OSREV >= 54)#define SOLARIS24#endif#if (OSREV == 551)#undef OSREV#define OSREV 55#endif#define USE_NEW_PROC#if defined(USE_NEW_PROC) && OSREV >= 56#define _STRUCTURED_PROC 1#define prpsinfo psinfo#include <sys/procfs.h>#define pr_fill pr_nlwp/* These require an ANSI C compiler "Reisser cpp" doesn't like this */#define pr_state pr_lwp.pr_state#define pr_oldpri pr_lwp.pr_oldpri#define pr_nice pr_lwp.pr_nice#define pr_pri pr_lwp.pr_pri#define pr_onpro pr_lwp.pr_onpro#define ZOMBIE(p)	((p)->pr_nlwp == 0)#define SIZE_K(p)	((p)->pr_size)#define RSS_K(p)	((p)->pr_rssize)#else#undef USE_NEW_PROC#define ZOMBIE(p)	((p)->pr_zomb)#define SIZE_K(p)	((p)->pr_bysize/1024)#define RSS_K(p)	((p)->pr_byrssize/1024)#define pr_onpro 	pr_filler[5]#endif#include "top.h"#include "machine.h"#include "utils.h"#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 <kvm.h>#include <sys/types.h>#include <sys/param.h>#include <sys/signal.h>#include <sys/fault.h>#include <sys/sysinfo.h>#include <sys/sysmacros.h>#include <sys/syscall.h>#include <sys/user.h>#include <sys/proc.h>#include <sys/procfs.h>#include <sys/vm.h>#include <sys/var.h>#include <sys/cpuvar.h>#include <sys/file.h>#include <sys/time.h>#include <sys/priocntl.h>#include <sys/tspriocntl.h>#include <sys/processor.h>#include <sys/swap.h>#include <vm/anon.h>#include <math.h>#if OSREV >= 53#define USE_KSTAT#endif#ifdef USE_KSTAT#include <kstat.h>/* * Some kstats are fixed at 32 bits, these will be specified as ui32; some * are "natural" size (32 bit on 32 bit Solaris, 64 on 64 bit Solaris * we'll make those unsigned long) * Older Solaris doesn't define KSTAT_DATA_UINT32, those are always 32 bit. */# ifndef KSTAT_DATA_UINT32#  define ui32 ul# endif#endif#define UNIX "/dev/ksyms"#define KMEM "/dev/kmem"#define PROCFS "/proc"#define CPUSTATES     5#ifndef PRIO_MIN#define PRIO_MIN	-20#endif#ifndef PRIO_MAX#define PRIO_MAX	20#endif#ifndef FSCALE#define FSHIFT  8		/* bits to right of fixed binary point */#define FSCALE  (1<<FSHIFT)#endif /* FSCALE */#define loaddouble(la) ((double)(la) / FSCALE)#define dbl_align(x)	(((unsigned long)(x)+(sizeof(double)-1)) & \						~(sizeof(double)-1))#ifdef SOLARIS24    /*     * snarfed from <sys/procfs.h>:     * The following percent numbers are 16-bit binary     * fractions [0 .. 1] with the binary point to the     * right of the high-order bit (one == 0x8000)     */#define percent_cpu(pp) (((double)pp->pr_pctcpu)/0x8000*100)#define weighted_cpu(pp) (*(double *)dbl_align(pp->pr_filler))#else#define percent_cpu(pp) (*(double *)dbl_align(&pp->pr_filler[0]))#define weighted_cpu(pp) (*(double *)dbl_align(&pp->pr_filler[2]))#endif/* definitions for indices in the nlist array */#define X_V			 0#define X_MPID			 1#define X_ANONINFO		 2#define X_MAXMEM		 3#define X_SWAPFS_MINFREE	 4#define X_FREEMEM		 5#define X_AVAILRMEM		 6#define X_AVENRUN		 7#define X_CPU			 8#define X_NPROC			 9#define X_NCPUS		   	10static struct nlist nlst[] ={  {"v"},			/* 0 */	/* replaced by dynamic allocation */  {"mpid"},			/* 1 */#if OSREV >= 56  /* this structure really has some extra fields, but the first three match */  {"k_anoninfo"},		/* 2 */#else  {"anoninfo"},			/* 2 */#endif  {"maxmem"},			/* 3 */ /* use sysconf */  {"swapfs_minfree"},		/* 4 */	/* used only w/ USE_ANONINFO */  {"freemem"},			/* 5 */	/* available from kstat >= 2.5 */  {"availrmem"},		/* 6 */	/* available from kstat >= 2.5 */  {"avenrun"},			/* 7 */ /* available from kstat */  {"cpu"},			/* 8 */ /* available from kstat */  {"nproc"},			/* 9 */ /* available from kstat */  {"ncpus"},			/* 10 */ /* available from kstat */  {0}};static unsigned long avenrun_offset;static unsigned long mpid_offset;#ifdef USE_KSTAT#define NO_NPROCstatic kstat_ctl_t *kc = NULL;static kstat_t **cpu_ks;static cpu_stat_t *cpu_stat;#elsestatic unsigned long *cpu_offset;#endifstatic unsigned long nproc_offset;static unsigned long freemem_offset;static unsigned long maxmem_offset;static unsigned long availrmem_offset;static unsigned long swapfs_minfree_offset;static unsigned long anoninfo_offset;static void reallocproc(int n);static int maxprocs;/* 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 */  };/* * Structure for keeping track of CPU times from last time around * the program.  We keep these things in a hash table, which is * recreated at every cycle. */struct oldproc  {    pid_t oldpid;    double oldtime;    double oldpct;  };int oldprocs;			/* size of table */#define HASH(x) ((x << 1) % oldprocs)/* * GCC assumes that all doubles are aligned.  Unfortunately it * doesn't round up the structure size to be a multiple of 8. * Thus we'll get a coredump when going through array.  The * following is a size rounded up to 8. */#define PRPSINFOSIZE dbl_align(sizeof(struct prpsinfo))/* *  These definitions control the format of the per-process area */static char header[] ="  PID X        THR PRI NICE  SIZE   RES STATE   TIME    CPU COMMAND";/* 0123456   -- field to fill in starts at header+6 */#define UNAME_START 6#define Proc_format \        "%5d %-8.8s %3d %3d %4d %5s %5s %-5s %6s %5.2f%% %s"/* process state names for the "STATE" column of the display *//* the extra nulls in the string "run" are for adding a slash and   the processor number when needed */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", "iowait", "swap", NULL};#define CPUSTATE_IOWAIT 3#define CPUSTATE_SWAP   4/* these are for detailing the memory statistics */int memory_stats[5];char *memorynames[] ={"K real, ", "K active, ", "K free, ", "K swap in use, ", "K swap free", NULL};/* these are names given to allowed sorting orders -- first is default */char *ordernames[] = {"cpu", "size", "res", "time", NULL};/* forward definitions for comparison functions */int compare_cpu();int compare_size();int compare_res();int compare_time();int (*proc_compares[])() = {    compare_cpu,    compare_size,    compare_res,    compare_time,    NULL };kvm_t *kd;static DIR *procdir;static int nproc;static int ncpus;/* these are for keeping track of the proc array */static int bytes;static struct prpsinfo *pbase;static struct prpsinfo **pref;static struct oldproc *oldbase;/* pagetok function is really a pointer to an appropriate function */static int pageshift;static int (*p_pagetok) ();#define pagetok(size) ((*p_pagetok)(size))/* useful externals */extern char *myname;extern int check_nlist ();extern int gettimeofday ();extern int getkval ();extern void perror ();extern void getptable ();extern void quit ();extern int nlist ();int pagetok_none(int size){    return(size);}int pagetok_left(int size){    return(size << pageshift);}int pagetok_right(int size){    return(size >> pageshift);}intmachine_init (struct statics *statics){    static struct var v;    struct oldproc *op, *endbase;    int i;#ifndef USE_KSTAT    int offset;#endif    /* perform the kvm_open */    kd = kvm_open (NULL, NULL, NULL, O_RDONLY, "top");    /*     * turn off super group/user privs - but beware; we might     * want the privs back later and we still have a fd to     * /dev/kmem open so we can't use setgid()/setuid() as that     * would allow a debugger to attach to this process. CD     */    setegid(getgid());    seteuid(getuid()); /* super user not needed for NEW_PROC */    /* fill in the statics information */    statics->procstate_names = procstatenames;    statics->cpustate_names = cpustatenames;    statics->memory_names = memorynames;    statics->order_names = ordernames;    /* test kvm_open return value */    if (kd == NULL)      {	perror ("kvm_open");#ifndef USE_KSTAT	return (-1);#endif      }    if (kd)      {      if (kvm_nlist (kd, nlst) < 0)        {	  perror ("kvm_nlist");	  return (-1);        }      if (check_nlist (nlst) != 0)        return (-1);      }#ifndef NO_NPROC    /* 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;    reallocproc(nproc);#endif    /* 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;    freemem_offset = nlst[X_FREEMEM].n_value;    maxmem_offset = nlst[X_MAXMEM].n_value;    availrmem_offset = nlst[X_AVAILRMEM].n_value;    swapfs_minfree_offset = nlst[X_SWAPFS_MINFREE].n_value;#ifndef USE_KSTAT    (void) getkval (nlst[X_NCPUS].n_value, (int *) (&ncpus),		    sizeof (ncpus), "ncpus");    cpu_offset = (unsigned long *) malloc (ncpus * sizeof (unsigned long));    for (i = offset = 0; i < ncpus; offset += sizeof(unsigned long)) {        (void) getkval (nlst[X_CPU].n_value + offset,                        &cpu_offset[i], sizeof (unsigned long),                        nlst[X_CPU].n_name );        if (cpu_offset[i] != 0)            i++;    }#endif    /* calculate pageshift value */    i = sysconf(_SC_PAGESIZE);    pageshift = 0;    while ((i >>= 1) > 0)    {	pageshift++;    }    /* calculate an amount to shift to K values */    /* remember that log base 2 of 1024 is 10 (i.e.: 2^10 = 1024) */    pageshift -= 10;    /* now determine which pageshift function is appropriate for the        result (have to because x << y is undefined for y < 0) */    if (pageshift > 0)    {	/* this is the most likely */	p_pagetok = pagetok_left;    }    else if (pageshift == 0)    {	p_pagetok = pagetok_none;    }    else    {	p_pagetok = pagetok_right;	pageshift = -pageshift;    }    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);      }    /* all done! */    return (0);  }char *format_header (register char *uname_field){  register char *ptr;  ptr = header + UNAME_START;  while (*uname_field != '\0')    *ptr++ = *uname_field++;  return (header);}#ifdef USE_KSTAT#define UPDKCID(nk,ok) \if (nk == -1) { \  perror("kstat_read "); \  quit(1); \} \if (nk != ok)\

⌨️ 快捷键说明

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