📄 m_linuxthr.c
字号:
gettimeofday(&thistime, 0); if (lasttime.tv_sec) { timediff = ((thistime.tv_sec - lasttime.tv_sec) + (thistime.tv_usec - lasttime.tv_usec) * 1e-6); } else timediff = 1e9; lasttime = thistime; /* calculate constants for the exponental average */ if (timediff < 30.0) { alpha = 0.5 * (timediff / 30.0); beta = 1.0 - alpha; } else alpha = beta = 0.5; timediff *= HZ; /* convert to ticks */ /* mark all hash table entries as not seen */ for (i = 0; i < HASH_SIZE; ++i) { for (proc = ptable[i]; proc; proc = proc->next) { proc->state = 0; } } /* read the process information */ { DIR *dir = opendir("."); struct dirent *ent; int total_procs = 0; struct top_proc **active; int show_idle = sel->idle; int show_uid = sel->uid != -1; memset(process_states, 0, sizeof(process_states)); while ((ent = readdir(dir)) != NULL) { struct top_proc *pp; unsigned long otime; if (!isdigit(ent->d_name[0])) continue; pid = atoi(ent->d_name); /* look up hash table entry */ proc = pp = ptable[HASH(pid)]; while (proc && proc->pid != pid) { proc = proc->next; } /* if we came up empty, create a new entry */ if (proc == NULL) { proc = new_proc(); proc->pid = pid; proc->next = pp; ptable[HASH(pid)] = proc; proc->time = proc->otime = 0; } read_one_proc_stat(pid, proc); proc->threads = 1; if (proc->state == 0) continue; /* calculate cpu percentage */ proc->pcpu = (proc->time - proc->otime) / timediff; proc->otime = proc->time; total_procs++; process_states[proc->state]++; } closedir(dir); /* make sure we have enough slots for the active procs */ if (activesize < total_procs) { pactive = (struct top_proc **)realloc(pactive, sizeof(struct top_proc *) * total_procs); activesize = total_procs; } /* set up the active procs and flush dead entries */ /* also coalesce threads */ active = pactive; for (i = 0; i < HASH_SIZE; i++) { struct top_proc *last; struct top_proc *ptmp; struct top_proc *parent; last = NULL; proc = ptable[i]; while (proc != NULL) { if (proc->state == 0) { ptmp = proc; if (last) { proc = last->next = proc->next; } else { proc = ptable[i] = proc->next; } free_proc(ptmp); } else { /* look up hash table entry for parent */ parent = proc; do { pid = parent->ppid; parent = ptable[HASH(pid)]; while (parent && parent->pid != pid) { parent = parent->next; } } while (parent && parent->state == 0); /* does this look like a thread of its parent? */ if (parent && proc->size == parent->size && proc->rss == parent->rss && proc->start_code == parent->start_code && proc->end_code == parent->end_code && proc->start_stack == parent->start_stack) { /* yes it does: roll up the cumulative numbers */ parent->threads += proc->threads; parent->time += proc->time; parent->pcpu += proc->pcpu; /* mark this process as dead (undisplayable) */ proc->state = 0; } else if ((show_idle || proc->state == 1 || proc->pcpu) && (!show_uid || proc->uid == sel->uid)) { *active++ = proc; last = proc; } proc = proc->next; } } } si->p_active = active - pactive; si->p_total = total_procs; si->procstates = process_states; } /* if requested, sort the "active" procs */ if (compare && si->p_active) qsort(pactive, si->p_active, sizeof(struct top_proc *), compare); /* don't even pretend that the return value thing here isn't bogus */ nextactive = pactive; return (caddr_t)0;}char *format_header(uname_field) char *uname_field;{ int uname_len = strlen(uname_field); if (uname_len > 8) uname_len = 8; memcpy(strchr(fmt_header, 'X'), uname_field, uname_len); return fmt_header;}char *format_next_process(handle, get_userid) caddr_t handle; char *(*get_userid)();{ static char fmt[128]; /* static area where result is built */ struct top_proc *p = *nextactive++; sprintf(fmt, "%5d %-8.8s %3d %3d %4d %5s %5s %-5s %6s %5.2f%% %.16s", p->pid, (*get_userid)(p->uid), p->threads, p->pri < -99 ? -99 : p->pri, p->nice, format_k(p->size), format_k(p->rss), state_abbrev[p->state], format_time(p->time / HZ), p->pcpu * 100.0, p->name); /* return the result */ return (fmt);}#ifdef ORDER/* comparison routines for qsort *//* * There are currently four possible comparison routines. main selects * one of these by indexing in to the array proc_compares. * * Possible keys are defined as macros below. Currently these keys are * defined: percent cpu, cpu ticks, process state, resident set size, * total virtual memory usage. The process states are ordered as follows * (from least to most important): WAIT, zombie, sleep, stop, start, run. * The array declaration below maps a process state index into a number * that reflects this ordering. *//* First, the possible comparison keys. These are defined in such a way that they can be merely listed in the source code to define the actual desired ordering. */#define ORDERKEY_PCTCPU if (dresult = p2->pcpu - p1->pcpu,\ (result = dresult > 0.0 ? 1 : dresult < 0.0 ? -1 : 0) == 0)#define ORDERKEY_CPTICKS if ((result = p2->time - p1->time) == 0)#define ORDERKEY_STATE if ((result = (sort_state[p2->state] - \ sort_state[p1->state])) == 0)#define ORDERKEY_PRIO if ((result = p2->pri - p1->pri) == 0)#define ORDERKEY_RSSIZE if ((result = p2->rss - p1->rss) == 0)#define ORDERKEY_MEM if ((result = p2->size - p1->size) == 0)/* Now the array that maps process state to a weight */unsigned char sort_state[] ={ 0, /* empty */ 6, /* run */ 3, /* sleep */ 5, /* disk wait */ 1, /* zombie */ 2, /* stop */ 4 /* swap */};/* compare_cpu - the comparison function for sorting by cpu percentage */intcompare_cpu ( struct top_proc **pp1, struct top_proc **pp2) { register struct top_proc *p1; register struct top_proc *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 == 0 ? 0 : result < 0 ? -1 : 1; }/* compare_size - the comparison function for sorting by total memory usage */intcompare_size ( struct top_proc **pp1, struct top_proc **pp2) { register struct top_proc *p1; register struct top_proc *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 == 0 ? 0 : result < 0 ? -1 : 1; }/* compare_res - the comparison function for sorting by resident set size */intcompare_res ( struct top_proc **pp1, struct top_proc **pp2) { register struct top_proc *p1; register struct top_proc *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 == 0 ? 0 : result < 0 ? -1 : 1; }/* compare_time - the comparison function for sorting by total cpu time */intcompare_time ( struct top_proc **pp1, struct top_proc **pp2) { register struct top_proc *p1; register struct top_proc *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 == 0 ? 0 : result < 0 ? -1 : 1; }#else /* ORDER *//* * proc_compare - comparison function for "qsort" * Compares the resource consumption of two processes using five * distinct keys. The keys (in descending order of importance) are: * percent cpu, cpu ticks, state, resident set size, total virtual * memory usage. The process states are ordered as follows (from least * to most important): WAIT, zombie, sleep, stop, start, run. The * array declaration below maps a process state index into a number * that reflects this ordering. */intproc_compare (pp1, pp2) struct top_proc **pp1, **pp2;{ static unsigned char sort_state[] = { 0, /* empty */ 6, /* run */ 3, /* sleep */ 5, /* disk wait */ 1, /* zombie */ 2, /* stop */ 4 /* swap */ }; struct top_proc *p1, *p2; int result; double dresult; /* remove one level of indirection */ p1 = *pp1; p2 = *pp2; /* compare percent cpu (pctcpu) */ dresult = p2->pcpu - p1->pcpu; if (dresult != 0.0) return dresult > 0.0 ? 1 : -1; /* use cputicks to break the tie */ if ((result = p2->time - p1->time) == 0) { /* use process state to break the tie */ if ((result = (sort_state[p2->state] - sort_state[p1->state])) == 0) { /* use priority to break the tie */ if ((result = p2->pri - p1->pri) == 0) { /* use resident set size (rssize) to break the tie */ if ((result = p2->rss - p1->rss) == 0) { /* use total memory to break the tie */ result = (p2->size - p1->size); } } } } return result == 0 ? 0 : result < 0 ? -1 : 1;}#endif /* ORDER *//* * 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) pid_t pid;{ struct stat sb; char buffer[32]; sprintf(buffer, "%d", pid); if (stat(buffer, &sb) < 0) return -1; else return sb.st_uid;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -