📄 perfmeter.c
字号:
register int i, *dp, old, tmp; register struct meter *mp; if (dead) return; if (vers == RSTATVERS_VAR) dp = getdata_var(); else dp = getdata_swtch(); if (dp == NULL) { dead = 1; sick = 0; meter_paint(); keeptrying(); return; } /* * Don't have to worry about save[old] being -1 the * very first time thru, because we are called * before save is initialized to -1. */ old = saveptr; if (++saveptr == MAXSAVE) saveptr = 0; for (i = 0, mp = meters; i < length; i++, mp++, dp++) { if (*dp < 0) /* should print out warning if this happens */ *dp = 0; tmp = (longexp * save_access(i, old) + (*dp * FSCALE)/mp->m_scale * (FSCALE - longexp)) >> FSHIFT; if (tmp < 0) /* check for wraparound */ tmp = mp->m_curmax * FSCALE; save_access(i, saveptr) = tmp; tmp = (shortexp * mp->m_longave + (*dp * FSCALE/mp->m_scale) * (FSCALE - shortexp)) >> FSHIFT; if (tmp < 0) /* check for wraparound */ tmp = mp->m_curmax * FSCALE; mp->m_longave = tmp; }}getminutedata(){ return (save_access(visible, saveptr));}gethourdata(){ return (meters[visible].m_longave);}/* * Initialize the connection to the metered host. */static CLIENT *client, *oldclient;static intsetup(){ struct timeval timeout; enum clnt_stat clnt_stat; struct hostent *hp; struct sockaddr_in serveradr; int snum; snum = RPC_ANYSOCK; bzero((char *)&serveradr, sizeof (serveradr)); if (hostname) { if ((hp = gethostbyname(hostname)) == NULL) { (void)fprintf(stderr, "Sorry, host %s not in hosts database\n", hostname); exit(1); } bcopy(hp->h_addr, (char *)&serveradr.sin_addr, hp->h_length); } else { if (hp = gethostbyname("localhost")) bcopy(hp->h_addr, (char *)&serveradr.sin_addr, hp->h_length); else serveradr.sin_addr.s_addr = inet_addr("127.0.0.1"); } serveradr.sin_family = AF_INET; serveradr.sin_port = 0; timeout.tv_sec = 5; timeout.tv_usec = 0; if ((vers == VER_NONE) || (vers == RSTATVERS_VAR)) { if ((client = clntudp_bufcreate(&serveradr, RSTATPROG, RSTATVERS_VAR, timeout, &snum, sizeof(struct rpc_msg), UDPMSGSIZE)) == NULL) return (-1); clnt_stat = clnt_call(client, NULLPROC, xdr_void, 0,xdr_void, 0, TIMEOUT); if (clnt_stat == RPC_SUCCESS) { vers = RSTATVERS_VAR; } else if (clnt_stat != RPC_PROGVERSMISMATCH) { clnt_destroy(client); return(-1); } else { /* version mismatch */ clnt_destroy(client); vers = RSTATVERS_SWTCH; } } if ((vers == VER_NONE) || (vers == RSTATVERS_SWTCH)) { snum = RPC_ANYSOCK; if ((client = clntudp_bufcreate(&serveradr, RSTATPROG, RSTATVERS_SWTCH, timeout, &snum, sizeof(struct rpc_msg), sizeof(struct rpc_msg) + sizeof(struct statsswtch)))== NULL) return (-1); clnt_stat = clnt_call(client, NULLPROC, xdr_void, 0, xdr_void, 0, TIMEOUT); if (clnt_stat == RPC_SUCCESS) { vers = RSTATVERS_SWTCH; } else { clnt_destroy(client); return (-1); } } if (oldsocket >= 0) (void)close(oldsocket); oldsocket = snum; if (oldclient) clnt_destroy(oldclient); oldclient = client; return (0);}/* * Fork a separate process to keep trying to contact the host * so that the main process can continue to service window * requests (repaint, move, stretch, etc.). */keeptrying(){ int pid; if ((int)signal(SIGCHLD, ondeath) == -1) perror("signal"); pid = fork(); if (pid < 0) { perror("fork"); exit(1); } if (pid == 0) { for (;;) { sleep(1); if (setup() < 0) continue; exit(0); } }}/* * Kill any background processes we may've started. */killkids(){ (void)signal(SIGINT, SIG_IGN); (void)signal(SIGCHLD, SIG_IGN); (void)killpg(getpgrp(0), SIGINT); /* get rid of forked processes */ exit(0);}/* * Get the metered data from the host via RPC * and process it to compute the actual values * (rates) that perfmeter wants to see. *//* static data used only by getdata_swtch() and getdata_var() */static statsswtch statswtch;static statsvar stats_var;static int *oldtime;static int total; /* Default to zero */static int toterr; /* Default to zero */static int totcoll; /* Default to zero */static struct timeval tm, oldtm;static int *xfer1;static int badcnt; /* Default to zero */static int ans[MAXMETERS];static int oldi, olds, oldp, oldsp;static int getdata_init_done; /* Default to zero */static int cpustates;static int dk_ndrive;int *getdata_swtch(){ register int i, t; register int msecs; int maxtfer; enum clnt_stat clnt_stat; int intrs, swtchs, pag, spag; int sum, ppersec; clnt_stat = clnt_call(client, RSTATPROC_STATS, xdr_void, 0, xdr_statsswtch, &statswtch, TIMEOUT); if (clnt_stat == RPC_TIMEDOUT) return (NULL); if (clnt_stat != RPC_SUCCESS) { if (!sick) { clnt_perror(client, "cpugetdata"); sick = 1; } meter_paint(); return (NULL); } if (oldtime == (int *)NULL) { /* allocate memory for structures */ cpustates = 4; /* compatibility with version 3*/ dk_ndrive = 4; oldtime = (int *) malloc(cpustates * sizeof(int)); xfer1 = (int *) malloc(dk_ndrive * sizeof(int)); if ( (oldtime == NULL) || (xfer1 == NULL)) { fprintf(stderr,"failed in malloc()\n"); exit(1); } } for (i = 0; i < cpustates; i++) { t = statswtch.cp_time[i]; statswtch.cp_time[i] -= oldtime[i]; oldtime[i] = t; } t = 0; for (i = 0; i < cpustates -1; i++) /* assume IDLE is last */ t += statswtch.cp_time[i]; if (statswtch.cp_time[cpustates -1] + t <= 0) { t++; badcnt++; if (badcnt >= TRIES) { sick = 1; meter_paint(); } } else if (sick) { badcnt = sick = 0; meter_paint(); } else { badcnt = 0; } ans[CPU] = (100*t) / (statswtch.cp_time[cpustates - 1] + t); (void)gettimeofday(&tm, (struct timezone *)0); msecs = (1000 * (tm.tv_sec - oldtm.tv_sec) + (tm.tv_usec - oldtm.tv_usec)/1000); msecs++; /* round up 1ms to avoid msecs == 0 */ sum = statswtch.if_ipackets + statswtch.if_opackets; ppersec = 1000*(sum - total) / msecs; total = sum; ans[PKTS] = ppersec; ans[COLL] = FSCALE*(statswtch.if_collisions - totcoll)*1000 / msecs; totcoll = statswtch.if_collisions; ans[ERR] = FSCALE*(statswtch.if_ierrors - toterr)*1000 / msecs; toterr = statswtch.if_ierrors; if (!getdata_init_done) { pag = 0; spag = 0; intrs = 0; swtchs = 0; getdata_init_done = 1; } else { pag = statswtch.v_pgpgout + statswtch.v_pgpgin - oldp; pag = 1000*pag / msecs; spag = statswtch.v_pswpout + statswtch.v_pswpin - oldsp; spag = 1000*spag / msecs; intrs = statswtch.v_intr - oldi; intrs = 1000*intrs / msecs; swtchs = statswtch.v_swtch - olds; swtchs = 1000*swtchs / msecs; } oldp = statswtch.v_pgpgin + statswtch.v_pgpgout; oldsp = statswtch.v_pswpin + statswtch.v_pswpout; oldi = statswtch.v_intr; olds = statswtch.v_swtch; ans[PAGE] = pag; ans[SWAP] = spag; ans[INTR] = intrs; ans[CNTXT] = swtchs; ans[LOAD] = statswtch.avenrun[0]; for (i = 0; i < dk_ndrive; i++) { t = statswtch.dk_xfer[i]; statswtch.dk_xfer[i] -= xfer1[i]; xfer1[i] = t; }/* Bug# 1028570 fix, old code commented out * * maxtfer = statswtch.dk_xfer[0]; * for (i = 1; i < dk_ndrive; i++) * if (statswtch.dk_xfer[i] > maxtfer) * maxtfer = statswtch.dk_xfer[i]; */ for (i = 0, maxtfer = 0; i < dk_ndrive; i++) maxtfer += statswtch.dk_xfer[i]; maxtfer = (1000*maxtfer) / msecs; ans[DISK] = maxtfer; oldtm = tm; return (ans);}int *getdata_var(){ register int i, t; register int msecs; int maxtfer; enum clnt_stat clnt_stat; int intrs, swtchs, pag, spag; int sum, ppersec; if (oldtime == (int *) NULL) { stats_var.dk_xfer.dk_xfer_val = (int *) NULL; stats_var.cp_time.cp_time_val = (int *) NULL; } clnt_stat = clnt_call(client, RSTATPROC_STATS, xdr_void, 0, xdr_statsvar, &stats_var, TIMEOUT); if (clnt_stat == RPC_TIMEDOUT) return (NULL); if (clnt_stat != RPC_SUCCESS) { if (!sick) { clnt_perror(client, "cpugetdata"); sick = 1; } meter_paint(); return (NULL); } if ( oldtime == (int * ) NULL) { /* allocate memory for structures */ cpustates = stats_var.cp_time.cp_time_len; dk_ndrive = stats_var.dk_xfer.dk_xfer_len; oldtime = (int *) malloc(cpustates * sizeof(int)); xfer1 = (int *) malloc(dk_ndrive * sizeof(int)); if ( (oldtime == NULL) || (xfer1 == NULL)) { fprintf(stderr,"failed in malloc()\n"); exit(1); } } for (i = 0; i < cpustates; i++) { t = stats_var.cp_time.cp_time_val[i]; stats_var.cp_time.cp_time_val[i] -= oldtime[i]; oldtime[i] = t; } t = 0; for (i = 0; i < cpustates - 1 ; i++) /* assume IDLE is last */ t += stats_var.cp_time.cp_time_val[i]; if (stats_var.cp_time.cp_time_val[cpustates - 1 ] + t <= 0) { t++; badcnt++; if (badcnt >= TRIES) { sick = 1; meter_paint(); } } else if (sick) { badcnt = sick = 0; meter_paint(); } else { badcnt = 0; } ans[CPU] = (100*t) / (stats_var.cp_time.cp_time_val[cpustates - 1 ] + t); (void)gettimeofday(&tm, (struct timezone *)0); msecs = (1000*(tm.tv_sec - oldtm.tv_sec) + (tm.tv_usec - oldtm.tv_usec)/1000); msecs++; /* round up 1ms to avoid msecs == 0 */ /* * (Bug# 1013912 fix) in the rare occurence that msecs = 0, * reset to msecs = 1 to ensure no "divide by zero" * errors later. */ if (msecs == 0) msecs = 1; sum = stats_var.if_ipackets + stats_var.if_opackets; ppersec = 1000*(sum - total) / msecs; total = sum; ans[PKTS] = ppersec; ans[COLL] = FSCALE*(stats_var.if_collisions - totcoll)*1000 / msecs; totcoll = stats_var.if_collisions; ans[ERR] = FSCALE*(stats_var.if_ierrors - toterr)*1000 / msecs; toterr = stats_var.if_ierrors; if (!getdata_init_done) { pag = 0; spag = 0; intrs = 0; swtchs = 0; getdata_init_done = 1; } else { pag = stats_var.v_pgpgout + stats_var.v_pgpgin - oldp; pag = 1000*pag / msecs; spag = stats_var.v_pswpout + stats_var.v_pswpin - oldsp; spag = 1000*spag / msecs; intrs = stats_var.v_intr - oldi; intrs = 1000*intrs / msecs; swtchs = stats_var.v_swtch - olds; swtchs = 1000*swtchs / msecs; } oldp = stats_var.v_pgpgin + stats_var.v_pgpgout; oldsp = stats_var.v_pswpin + stats_var.v_pswpout; oldi = stats_var.v_intr; olds = stats_var.v_swtch; ans[PAGE] = pag; ans[SWAP] = spag; ans[INTR] = intrs; ans[CNTXT] = swtchs; ans[LOAD] = stats_var.avenrun[0]; for (i = 0; i < dk_ndrive; i++) { t = stats_var.dk_xfer.dk_xfer_val[i]; stats_var.dk_xfer.dk_xfer_val[i] -= xfer1[i]; xfer1[i] = t; }/* Bug# 1028570 fix, old code commented out * * maxtfer = stats_var.dk_xfer.dk_xfer_val[0]; * for (i = 1; i < dk_ndrive; i++) * if (stats_var.dk_xfer.dk_xfer_val[i] > maxtfer) * maxtfer = stats_var.dk_xfer.dk_xfer_val[i]; */ for (i = 0, maxtfer = stats_var.dk_xfer.dk_xfer_val[0]; i < dk_ndrive; i++) maxtfer += stats_var.dk_xfer.dk_xfer_val[i]; maxtfer = (1000*maxtfer) / msecs; ans[DISK] = maxtfer; oldtm = tm; return (ans);}static caddr_tdo_menu(menu, mi) Menu menu; Menu_item mi;{ int n; n = (int)menu_get(mi, MENU_VALUE); /* BUG: WOrkaround ; There should be another way of doing this */ if (strcmp("frame", (char *)menu_get(mi, MENU_STRING))) visible = n; meter_paint(); return(mi);}staticNotify_valuemeter_itimer_expired(meter, which) Notify_client meter; int which;{ struct itimerval itimer; updatedata(); itimer = NOTIFY_NO_ITIMER; itimer.it_value.tv_sec = sampletime; meter_update(); (void) notify_set_itimer_func((Notify_client)(&meter_client), meter_itimer_expired, ITIMER_REAL, &itimer, (struct itimerval *)0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -