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

📄 m_linuxthr.c

📁 unix系统下top命令的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    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 + -