📄 machine.c
字号:
2, /* zombie */ 4, /* stop */ 5, /* start */ 7, /* run on a processor */ 1 /* being swapped (WAIT) */};/* compare_cpu - the comparison function for sorting by cpu percentage */intcompare_cpu ( struct prpsinfo **pp1, struct prpsinfo **pp2) { register struct prpsinfo *p1; register struct prpsinfo *p2; register long result; double dresult; /* remove one level of indirection */ p1 = *pp1; p2 = *pp2; ORDERKEY_PCTCPU ORDERKEY_CPTICKS ORDERKEY_STATE ORDERKEY_PRIO ORDERKEY_RSSIZE ORDERKEY_MEM ; return (result); }/* compare_size - the comparison function for sorting by total memory usage */intcompare_size ( struct prpsinfo **pp1, struct prpsinfo **pp2) { register struct prpsinfo *p1; register struct prpsinfo *p2; register long result; double dresult; /* remove one level of indirection */ p1 = *pp1; p2 = *pp2; ORDERKEY_MEM ORDERKEY_RSSIZE ORDERKEY_PCTCPU ORDERKEY_CPTICKS ORDERKEY_STATE ORDERKEY_PRIO ; return (result); }/* compare_res - the comparison function for sorting by resident set size */intcompare_res ( struct prpsinfo **pp1, struct prpsinfo **pp2) { register struct prpsinfo *p1; register struct prpsinfo *p2; register long result; double dresult; /* remove one level of indirection */ p1 = *pp1; p2 = *pp2; ORDERKEY_RSSIZE ORDERKEY_MEM ORDERKEY_PCTCPU ORDERKEY_CPTICKS ORDERKEY_STATE ORDERKEY_PRIO ; return (result); }/* compare_time - the comparison function for sorting by total cpu time */intcompare_time ( struct prpsinfo **pp1, struct prpsinfo **pp2) { register struct prpsinfo *p1; register struct prpsinfo *p2; register long result; double dresult; /* remove one level of indirection */ p1 = *pp1; p2 = *pp2; ORDERKEY_CPTICKS ORDERKEY_PCTCPU ORDERKEY_STATE ORDERKEY_PRIO ORDERKEY_MEM ORDERKEY_RSSIZE ; return (result); }/*get process table V.4 only has a linked list of processes so we want to follow that linked list, get all the process structures, and put them in our own table*/voidgetptable (struct prpsinfo *baseptr){ struct prpsinfo *currproc; /* pointer to current proc structure */#ifndef USE_NEW_PROC struct prstatus prstatus; /* for additional information */#endif int numprocs = 0; int i; struct dirent *direntp; struct oldproc *op; static struct timeval lasttime = {0, 0}; struct timeval thistime; double timediff; double alpha, beta; struct oldproc *endbase; gettimeofday (&thistime, NULL); /* * To avoid divides, we keep times in nanoseconds. This is * scaled by 1e7 rather than 1e9 so that when we divide we * get percent. */ if (lasttime.tv_sec) timediff = ((double) thistime.tv_sec * 1.0e7 + ((double) thistime.tv_usec * 10.0)) - ((double) lasttime.tv_sec * 1.0e7 + ((double) lasttime.tv_usec * 10.0)); else timediff = 1.0e7; /* * constants for exponential average. avg = alpha * new + beta * avg * The goal is 50% decay in 30 sec. However if the sample period * is greater than 30 sec, there's not a lot we can do. */ if (timediff < 30.0e7) { alpha = 0.5 * (timediff / 30.0e7); beta = 1.0 - alpha; } else { alpha = 0.5; beta = 0.5; } endbase = oldbase + oldprocs; currproc = baseptr; /* before reading /proc files, turn on root privs */ /* (we don't care if this fails since it will be caught later) */#ifndef USE_NEW_PROC seteuid(0);#endif for (rewinddir (procdir); (direntp = readdir (procdir));) { int fd; char buf[30]; if (direntp->d_name[0] == '.') continue;#ifdef USE_NEW_PROC snprintf(buf, sizeof(buf), "%s/psinfo", direntp->d_name); if ((fd = open (buf, O_RDONLY)) < 0) continue; if (read(fd, currproc, sizeof(psinfo_t)) != sizeof(psinfo_t)) { (void) close (fd); continue; } #else if ((fd = open (direntp->d_name, O_RDONLY)) < 0) continue; if (ioctl (fd, PIOCPSINFO, currproc) < 0) { (void) close (fd); continue; } if (ioctl (fd, PIOCSTATUS, &prstatus) < 0) { /* not a show stopper -- just fill in the needed values */ currproc->pr_fill = 0; currproc->pr_onpro = 0; } else { /* copy over the values we need from prstatus */ currproc->pr_fill = (short)prstatus.pr_nlwp; currproc->pr_onpro = prstatus.pr_processor; }#endif /* * SVr4 doesn't keep track of CPU% in the kernel, so we have * to do our own. See if we've heard of this process before. * If so, compute % based on CPU since last time. * NOTE: Solaris 2.4 and higher do maintain CPU% in prpsinfo. */ op = oldbase + HASH (currproc->pr_pid); while (1) { if (op->oldpid == -1) /* not there */ break; if (op->oldpid == currproc->pr_pid) { /* found old data */#if (OSREV < 54) percent_cpu (currproc) = ((currproc->pr_time.tv_sec * 1.0e9 + currproc->pr_time.tv_nsec) - op->oldtime) / timediff;#endif weighted_cpu (currproc) = op->oldpct * beta + percent_cpu (currproc) * alpha; break; } op++; /* try next entry in hash table */ if (op == endbase) /* table wrapped around */ op = oldbase; } /* Otherwise, it's new, so use all of its CPU time */ if (op->oldpid == -1) {#if (OSREV >= 54) weighted_cpu (currproc) = percent_cpu (currproc);#else if (lasttime.tv_sec) { percent_cpu (currproc) = (currproc->pr_time.tv_sec * 1.0e9 + currproc->pr_time.tv_nsec) / timediff; weighted_cpu (currproc) = percent_cpu (currproc); } else { /* first screen -- no difference is possible */ percent_cpu (currproc) = 0.0; weighted_cpu (currproc) = 0.0; }#endif } numprocs++; currproc = (struct prpsinfo *) ((char *) currproc + PRPSINFOSIZE); (void) close (fd);#ifdef NO_NPROC /* Atypical place for growth */ if (numprocs >= maxprocs) { reallocproc(2 * numprocs); currproc = (struct prpsinfo *) ((char *)baseptr + PRPSINFOSIZE * numprocs); }#endif }#ifndef USE_NEW_PROC /* turn off root privs */ seteuid(getuid());#endif if (nproc != numprocs) nproc = numprocs; /* * Save current CPU time for next time around * For the moment recreate the hash table each time, as the code * is easier that way. */ oldprocs = 2 * nproc; endbase = oldbase + oldprocs; for (op = oldbase; op < endbase; op++) op->oldpid = -1; for (i = 0, currproc = baseptr; i < nproc; i++, currproc = (struct prpsinfo *) ((char *) currproc + PRPSINFOSIZE)) { /* find an empty spot */ op = oldbase + HASH (currproc->pr_pid); while (1) { if (op->oldpid == -1) break; op++; if (op == endbase) op = oldbase; } op->oldpid = currproc->pr_pid; op->oldtime = (currproc->pr_time.tv_sec * 1.0e9 + currproc->pr_time.tv_nsec); op->oldpct = weighted_cpu (currproc); } lasttime = thistime;}/* * proc_owner(pid) - returns the uid that owns process "pid", or -1 if * the process does not exist. * It is EXTREMLY IMPORTANT that this function work correctly. * If top runs setuid root (as in SVR4), then this function * is the only thing that stands in the way of a serious * security problem. It validates requests for the "kill" * and "renice" commands. */uid_tproc_owner (pid_t pid){ register struct prpsinfo *p; int i; for (i = 0, p = pbase; i < nproc; i++, p = (struct prpsinfo *) ((char *) p + PRPSINFOSIZE)) { if (p->pr_pid == pid) return (p->pr_uid); } return (-1);}#if OSREV < 55intsetpriority (int dummy, int who, int niceval){ int scale; int prio; pcinfo_t pcinfo; pcparms_t pcparms; tsparms_t *tsparms; strcpy (pcinfo.pc_clname, "TS"); if (priocntl (0, 0, PC_GETCID, (caddr_t) & pcinfo) == -1) return (-1); prio = niceval; if (prio > PRIO_MAX) prio = PRIO_MAX; else if (prio < PRIO_MIN) prio = PRIO_MIN; tsparms = (tsparms_t *) pcparms.pc_clparms; scale = ((tsinfo_t *) pcinfo.pc_clinfo)->ts_maxupri; tsparms->ts_uprilim = tsparms->ts_upri = -(scale * prio) / 20; pcparms.pc_cid = pcinfo.pc_cid; if (priocntl (P_PID, who, PC_SETPARMS, (caddr_t) & pcparms) == -1) return (-1); return (0);}#endif#ifndef USE_ANONINFOget_swapinfo(int *total, int *fr){#ifdef SC_AINFO struct anoninfo anon; if (swapctl(SC_AINFO, &anon) == -1) { *total = *fr = 0; return; } *total = anon.ani_max; *fr = anon.ani_max - anon.ani_resv;#else register int cnt, i; register int t, f; struct swaptable *swt; struct swapent *ste; static char path[256]; /* get total number of swap entries */ cnt = swapctl(SC_GETNSWP, 0); /* allocate enough space to hold count + n swapents */ swt = (struct swaptable *)malloc(sizeof(int) + cnt * sizeof(struct swapent)); if (swt == NULL) { *total = 0; *fr = 0; return; } swt->swt_n = cnt; /* fill in ste_path pointers: we don't care about the paths, so we point them all to the same buffer */ ste = &(swt->swt_ent[0]); i = cnt; while (--i >= 0) { ste++->ste_path = path; } /* grab all swap info */ swapctl(SC_LIST, swt); /* walk thru the structs and sum up the fields */ t = f = 0; ste = &(swt->swt_ent[0]); i = cnt; while (--i >= 0) { /* dont count slots being deleted */ if (!(ste->ste_flags & ST_INDEL) && !(ste->ste_flags & ST_DOINGDEL)) { t += ste->ste_pages; f += ste->ste_free; } ste++; } /* fill in the results */ *total = t; *fr = f; free(swt);#endif /* SC_AINFO */}#endif /* USE_ANONINFO *//* * When we reach a proc limit, we need to realloc the stuff. */static void reallocproc(int n){ int bytes; struct oldproc *op, *endbase; if (n < maxprocs) return; maxprocs = n; /* allocate space for proc structure array and array of pointers */ bytes = maxprocs * PRPSINFOSIZE; pbase = (struct prpsinfo *) realloc(pbase, bytes); pref = (struct prpsinfo **) realloc(pref, maxprocs * sizeof(struct prpsinfo *)); oldbase = (struct oldproc *) realloc(oldbase, 2 * maxprocs * sizeof(struct oldproc)); /* Just in case ... */ if (pbase == (struct prpsinfo *) NULL || pref == (struct prpsinfo **) NULL || oldbase == (struct oldproc *) NULL) { fprintf (stderr, "%s: can't allocate sufficient memory\n", myname); quit(1); } /* * We're growing from 0 to some number, only then we need to * init the oldproc stuff */ if (!oldprocs) { oldprocs = 2 * maxprocs; endbase = oldbase + oldprocs; for (op = oldbase; op < endbase; op++) op->oldpid = -1; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -