📄 m_svr42mp.c
字号:
/* * Get process id of last process. */ getkval (nextpid_offset, (void *)&(si->last_pid), sizeof (si->last_pid), "nextpid"); si->last_pid--; /* * Get load average array. */ getkval (avenrun_offset, (void *) avenrun, sizeof (avenrun), "avenrun"); /* * Convert load averages to doubles. */ for (i = 0; i < 3; i++) si->load_avg[i] = loaddouble (avenrun[i]); /* * Extract CPU percentages. */ /* * 1. Retrieve pointer to metrics data structure. */ getkval(offset_offset, (void *)&mlpp, sizeof (struct met_localdata_ptrs_p *), "met_localdata_ptrs_pp"); /* * 2. Retrieve metrics data structure. (ptr to metrics engine) */ getkval((unsigned long)mlpp, (void *)&mlp, sizeof (mlp), "met_localdata_ptrs_p"); /* * 3. Retrieve (first local metrics) plocalmet data structure. */ getkval((unsigned long)mlp.localdata_p[0], (void *)&plm, sizeof(struct plocalmet), "plocalmet"); percentages(CPUSTATES, cpu_states, plm.metp_cpu.mpc_cpu, cp_old, cp_diff); /* * Retrieve memory information. */ /* * 1. Get physical memory size. */ getkval(totalmem_offset, (void *)&totalmem, sizeof (unsigned long), "totalmem"); /* * 2. Get physical swap size, and amount of swap remaining. */ get_swapinfo(&totalswap, &totalswapfree); /* * Insert memory information into memory_stat structure. */ memory_stats[0] = totalmem >> 10; memory_stats[1] = pagetok(totalswap); memory_stats[2] = pagetok(totalswapfree); /* * Set arrays and strings. */ si->cpustates = cpu_states; si->memory = memory_stats;}/* ************************************************************************** *//* * Extract process information. */static struct handle handle;caddr_tget_process_info ( struct system_info *si, struct process_select *sel, int (*compare) ()){ register int i; register int j = 0; register int active_procs; register int total_procs; register struct uwproc **prefp; register struct uwproc *uwp; /* * These are copied out of sel for speed. */ int show_idle; int show_system; int show_uid; /* * 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; (void) memset (process_states, 0, sizeof (process_states)); prefp = pref; for (i = 0; i < numprocs; i++) { uwp = &pbase[i]; /* * Place pointers to each valid proc structure in pref[]. * Processes with P_SYS set are system processes---these * get ignored unless show_system is set. */ uwp->dummy = 0; if ((show_system || ((uwp->p.p_flag & P_SYS) == 0))) { total_procs++; if (ZOMBIE(uwp)) { process_states[ZOMBIESTATE]++; } else { if ( (show_idle || uwp->l.l_stat == SRUN || uwp->l.l_stat == SONPROC) && (!show_uid || uwp->ps.pr_uid == (uid_t)sel->uid)) { process_states[uwp->l.l_stat]++; prefp[j] = uwp; j++; active_procs++; } } } } /* * If requested, sort the "interesting" processes. */ if (compare != NULL) qsort ((void *) pref, active_procs, sizeof (struct uwproc *), 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);}/* ************************************************************************** *//* * Format the output string for a process. */char fmt[MAX_COLS]; /* static area where result is built */char *format_next_process ( caddr_t handle, char *(*get_userid) ()){ register struct uwproc *pp; struct handle *hp; register long cputime; register double pctcpu; /* * Find and remember the next proc structure. */ hp = (struct handle *) handle; pp = *(hp->next_proc++); hp->remaining--; (void) snprintf (fmt, MAX_COLS, PROC_FORMAT, pp->ps.pr_pid, (*get_userid) (pp->ps.pr_uid), pp->PR_pri,#ifdef SHOW_NICE pp->ps.pr_lwp.pr_nice,#else (u_short)pp->p.p_nlwp < 999 ? (u_short)pp->p.p_nlwp : 999,#endif format_k(pagetok (pp->ps.pr_size)), format_k(pagetok (pp->ps.pr_rssize)), state_abbrev[pp->PR_state], format_time(pp->PR_time.tv_sec), pp->wcpu, pp->pctcpu, pp->ps.pr_fname); /* * Return the result. */ return (fmt);}/* ************************************************************************** *//* * check_nlist(nlst) - checks the nlist to see if any symbols were not * found. For every symbol that was not found, a one-line * message is printed to stderr. The routine returns the * number of symbols NOT found. */intcheck_nlist (register struct nlist *nlst){ register int i; /* * Check to see if we got ALL the symbols we requested. * This will write one line to stderr for every symbol not found. */ i = 0; while (nlst->n_name != NULL) { if (nlst->n_type == 0) { /* * This one wasn't found. */ fprintf(stderr, "kernel: no symbol named `%s'\n", nlst->n_name); i = 1; } nlst++; } return (i);}/* ************************************************************************** *//* * getkval(offset, ptr, size, refstr) - get a value out of the kernel. * "offset" is the byte offset into the kernel for the desired value, * "ptr" points to a buffer into which the value is retrieved, * "size" is the size of the buffer (and the object to retrieve), * "refstr" is a reference string used when printing error meessages, * if "refstr" starts with a '!', then a failure on read will not * be fatal (this may seem like a silly way to do things, but I * really didn't want the overhead of another argument). * */intgetkval ( unsigned long offset, void *ptr, int size, char *refstr){ if (lseek (kmem, (long) offset, 0) == -1) { if (*refstr == '!') refstr++; fprintf (stderr, "%s: lseek to %s: %s\n", myname, refstr, strerror(errno)); quit (22); } if (read (kmem, (char *) ptr, size) == -1) { if (*refstr == '!') { /* * We lost the race with the kernel, * process isn't in memory. */ return (0); } else { (void) fprintf (stderr, "%s: reading %s: %s\n", myname, refstr, strerror(errno)); quit (23); } } return (1);}/* ************************************************************************** *//* * Extract process table and derive %cpu figures.*/voidgetptable (struct uwproc *baseptr){ struct dirent *direntp; struct uwproc *curruwproc; struct oldproc *op; static struct timeval lasttime = {0, 0}; struct timeval thistime; double alpha, beta, timediff; int pos, i; numprocs = 0; gettimeofday(&thistime, NULL); /* * Calculate background information for CPU statistic. */ 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; } /* * While there are still entries (processes) in the /proc * filesystem to be examined... */ for (rewinddir (procdir); direntp = readdir (procdir);) { char buf[MAXPATHLEN]; int fd; int rc; int pos; /* * Ignore parent and current directory entries. */ if (direntp->d_name[0] == '.') continue; /* * Construct filename representing the psinfo * structure on disk. */ snprintf(buf, MAXPATHLEN, PROCFS "/%s/psinfo", direntp->d_name); if ((fd = open (buf, O_RDONLY)) == -1) { fprintf(stderr, "Can't open %s: %s\n", buf, strerror(errno)); continue; } curruwproc = &baseptr[numprocs]; /* * Read in psinfo structure from disk. */ if (read(fd, (void *)&curruwproc->ps, sizeof(psinfo_t)) != sizeof(psinfo_t)) { close(fd); fprintf(stderr, "Can't read %s: %s\n", buf, strerror(errno)); continue; } close(fd); /* * Extract the proc structure from the kernel. */ rc = getkval((unsigned long)curruwproc->ps.pr_addr, (void *)&curruwproc->p, sizeof(struct proc), "!proc"); if (rc == -1) { fprintf(stderr, "Can't read proc structure\n"); continue; } /* * Extract the lwp structure from the kernel. */ rc = getkval((unsigned long)curruwproc->ps.pr_lwp.pr_addr, (void *)&curruwproc->l, sizeof(struct lwp), "!lwp"); if (rc == -1) { fprintf(stderr, "Can't read lwp structure\n"); continue; } /* * Work out %cpu figure for process. */ pos = HASH(curruwproc->p.p_epid); while(1) { if (oldbase[pos].oldpid == -1) { /* * Process not present in hash. */ break; } if (oldbase[pos].oldpid == curruwproc->p.p_epid) { double new; /* * Found old data. */ new = (double)curruwproc->PR_time.tv_sec * 1.0e9 + curruwproc->PR_time.tv_nsec; curruwproc->pctcpu = (( (double)curruwproc->PR_time.tv_sec * 1.0e9 + (double)curruwproc->PR_time.tv_nsec) - (double)oldbase[pos].oldtime) / timediff; curruwproc->wcpu = oldbase[pos].oldpct * beta + curruwproc->pctcpu * alpha; break; } pos++; if (pos == numoldprocs) { pos = 0; } } if (oldbase[pos].oldpid == -1) { /* * New process. * All of its cputime used. */ if (lasttime.tv_sec) { curruwproc->pctcpu = (curruwproc->PR_time.tv_sec * 1.0e9 + curruwproc->PR_time.tv_nsec) / timediff; curruwproc->wcpu = curruwproc->pctcpu; } else { curruwproc->pctcpu = 0.0; curruwproc->wcpu = 0.0; } } numprocs++; } /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -