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

📄 m_ftx.c

📁 unix系统下top命令的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
  hp->remaining--;  /* get the cpu usage and calculate the cpu percentages */  cputime = pp->pr_time.tv_sec;  get_cpu(pp, &pctcpu, &pctwcpu);  /* format this entry */  (void) sprintf (fmt,		  Proc_format,		  pp->pr_pid,		  (*get_userid) (pp->pr_uid),		  pp->pr_pri - PZERO,		  pp->pr_nice - NZERO,		  pagetok (pp->pr_size),		  pagetok (pp->pr_rssize),		  state_abbrev[pp->pr_state],		  cputime / 60l,		  cputime % 60l,		  pctwcpu,		  pctcpu,		  pp->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 */	  (void) 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,	  int *ptr,	  int size,	  char *refstr){  if (lseek (kmem, (long) offset, 0) == -1)    {      if (*refstr == '!')	refstr++;      (void) fprintf (stderr, "%s: lseek to %s: %s\n",		      myname, refstr, sys_errlist[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, sys_errlist[errno]);	quit (23);      }  return (1);}/* comparison routine for qsort *//* *  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. */unsigned char sorted_state[] ={  0,				/* not used		*/  3,				/* sleep		*/  6,				/* run			*/  2,				/* zombie		*/  4,				/* stop			*/  5,				/* start		*/  7,				/* run on a processor   */  1				/* being swapped (WAIT)	*/};intproc_compare (	       struct prpsinfo **pp1,	       struct prpsinfo **pp2)  {    register struct prpsinfo *p1;    register struct prpsinfo *p2;    register long result;    register long d1;    register long d2;    register timedata_t *td;    /* remove one level of indirection */    p1 = *pp1;    p2 = *pp2;    td = get_timedata(p1);    if (td->ltime == -1)      d1 = 0;    else      d1 = td->time - td->ltime;    td = get_timedata(p2);    if (td->ltime == -1)      d2 = 0;    else      d2 = td->time - td->ltime;    /* compare cpu usage */    if ((result = d2 - d1) == 0)      {	/* use cpticks to break the tie */	if ((result = (PRTOMS(p2) - PRTOMS(p1))) == 0)	  {	    /* use process state to break the tie */	    if ((result = (long) (sorted_state[p2->pr_state] -				  sorted_state[p1->pr_state])) == 0)	      {		/* use priority to break the tie */		if ((result = p2->pr_oldpri - p1->pr_oldpri) == 0)		  {		    /* use resident set size (rssize) to break the tie */		    if ((result = p2->pr_rssize - p1->pr_rssize) == 0)		      {			/* use total memory to break the tie */			result = (p2->pr_size - p1->pr_size);		      }		  }	      }	  }      }    return (result);  }/*get process table*/voidgetptable (struct prpsinfo *baseptr){  struct prpsinfo *currproc;	/* pointer to current proc structure	*/  int numprocs = 0;  struct dirent *direntp;  for (rewinddir (procdir); direntp = readdir (procdir);)    {      int fd;      if ((fd = open (direntp->d_name, O_RDONLY)) < 0)	continue;      currproc = &baseptr[numprocs];      if (ioctl (fd, PIOCPSINFO, currproc) < 0)	{	  (void) close (fd);	  continue;	}      numprocs++;      (void) close (fd);    }  if (nproc != numprocs)    nproc = numprocs;}/* return the owner of the specified process, for use in commands.c as we're   running setuid root */uid_tproc_owner (pid_t pid){  register struct prpsinfo *p;  int i;  for (i = 0, p = pbase; i < nproc; i++, p++)    if (p->pr_pid == pid)      return (p->pr_uid);  return (-1);}intsetpriority (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);}/* * Per-process CPU calculation: * * We emulate actual % CPU usage calculation, since the statistics * kept by FTX are not valid for this purpose. We fake this calculation * by totalling the amount of CPU time used by all processes since the * last update, and dividing this into the CPU time used by the process * in question. For the WCPU value, we average the CPU calculations for the * process over the last td->cnt updates. This means that the first update * when starting top will always be 0% CPU (no big deal), and that WCPU will * be averaged over a varying amount of time (also no big deal). This is * probably the best we can do, since the kernel doesn't keep any of these * statistics itself. * * This method seems to yield good results. The only problems seem to be the * fact that the first update always shows 0%, and that the * sysinfo CPU data isn't always in sync with the per-process CPU usage * when a CPU-intensive process quits. This latter problem causes funny * results, because the remaining processes get credited with the residual * CPU time. * * This algorithm may seem CPU intensive, but it's actually very  * inexpensive. The expensive part is the ioctl call to the sar driver. * No amount of optimization in this program will reduce the sar overhead. */voidgetsysinfo (struct sysinfo *sysinfo){	register int i;	register int j;	register int cpus;	/* Get the per-CPU sysinfo data from sar. */	if(ioctl(sar, SAR_SYSINFO, &spa)) {		perror("ioctl(sar, SAR_SYSINFO)");		quit(24);	}	(void)memset((char *)sysinfo, 0, sizeof(struct sysinfo));	/* Average the state times to get systemwide values. */	for(i = 0, cpus = 0; i < MAX_LOG_CPU; i++) {		if(cpu_state[i] != SAR_CPU_RUNNING)			continue;		cpus++;		for(j = 0; j < 5; j++)			sysinfo->cpu[j] += cpu_sysinfo[i].cpu[j];	}	for(i = 0; i < 5; i++)		sysinfo->cpu[i] /= cpus;}voidadd_time (struct prpsinfo *pp){	register timedata_t *td;	td = get_timedata(pp);	td->flags |= TF_USED;	if(td->time == -1) {		td->time = PRTOMS(pp);		if(!(td->flags & TF_NEWPROC))			return;		td->flags &= ~TF_NEWPROC;		td->ltime = 0;	}	else {		td->ltime = td->time;		td->time = PRTOMS(pp);	}	/* Keep track of the time spent by all processes. */	total_time += td->time - td->ltime;}voidget_cpu(struct prpsinfo *pp, double *cpu, double *wcpu){	register int i;	register int j;	register long t;	register timedata_t *td;	td = get_timedata(pp);	/* No history, so return 0%. */	if(td->ltime == -1) {		*cpu = 0;		*wcpu = 0;		return;	}	i = td->index;	td->index = (i + 1) % MAXTIMEHIST;	td->cnt = MIN((td->cnt + 1), MAXTIMEHIST);	/* Compute CPU usage (time diff from last update / total cpu time). */	/* We don't want to div by 0. */	if(total_time == 0) {		td->hist[i] = 0;		*cpu = 0.0;	}	else {		t = (td->time - td->ltime) * 10000 / total_time * total_cpu;		td->hist[i] = t;		*cpu = t / 100.0;	}	/* Compute WCPU usage (average CPU % since oldest update). */	for(j = 0, t = 0; j < td->cnt; j++) {		t += td->hist[i];		i--;		if(i < 0)			i = MAXTIMEHIST - 1;	}	*wcpu = t / j / 100.0;}timedata_t *get_timedata(struct prpsinfo *pp){	register timedata_t *t;	register timedata_t *l;	l = TD_HASH(pp->pr_pid);	for(t = l->hnext; t != l; t = t->hnext)		if(t->pid == pp->pr_pid)			return t;	t = (timedata_t *)malloc(sizeof(timedata_t));	if(t == 0) {		perror("malloc");		quit(25);	}	t->pid = pp->pr_pid;	t->index = 0;	t->cnt = 0;	t->time = -1;	t->ltime = -1;	if(initted)		t->flags = TF_USED | TF_NEWPROC;	else		t->flags = TF_USED;	/* Put struct on hash list. */	t->hnext = l->hnext; 	t->hlast = l; 	l->hnext->hlast = t;	l->hnext = t;	/* Put struct on timedata list. */	t->lnext = timedata.lnext; 	t->llast = &timedata;	timedata.lnext->llast = t;	timedata.lnext = t;	return t;}voidclean_timedata(void){	register timedata_t *t;	for(t = timedata.lnext; t != &timedata; t = t->lnext) {		if(!(t->flags & TF_USED)) {			t->hnext->hlast = t->hlast;			t->hlast->hnext = t->hnext;			t->lnext->llast = t->llast;			t->llast->lnext = t->lnext;			free(t);		}		else {			t->flags &= ~TF_USED;		}	}}

⌨️ 快捷键说明

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