程序很简单,基本都在top.c里。
load里的cpu详细信息代码如下:
1 smpcpu = cpus_refresh(smpcpu);
2
3 if (CHKw(Curwin, View_CPUSUM)) {
4 // display just the 1st /proc/stat line
5 summaryhlp(&smpcpu[Cpu_tot], "Cpu(s):");
6 } else {
7 int i;
8 char tmp[SMLBUFSIZ];
9 // display each cpu's states separately
10 for (i = 0; i < Cpu_tot; i++) {
11 snprintf(tmp, sizeof(tmp), "Cpu%-3d:", smpcpu[i].id);
12 summaryhlp(&smpcpu[i], tmp);
13 }
14 }
Cpu_tot为cpu数量。
cpus_refresh函数里从/proc/stat文件里读入cpu信息,然后装入smpcpu里。smpcpu为大小为Cpu_tot+1个CPU_t成员的数组。
/proc/stat文件的头几行为:
cpu %d %d
cpu0 %d %d
cpu1 %d %d
第一行的cpu信息装入smpcpu[Cpu_tot],之后的cpu0\cpu1\...装入smpcpu[0]\smpcpu[1\...。
View_CPUSUM这个由1键来控制的那个开关,开关关闭时只显示smpcpu的Cpu_tot,开关开启时显示的是smpcpu的下标0~Cpu_tot-1的成员。即,top的默认在开头显示的cpu详细信息显示的是/proc/stat的第一行处理后,按下1键,显示的时/proc/stat后续各cpu数据。
/proc/stat里都是数字,下边看看top里显示的百分比怎么算的。
CPU_t的定义:
1 // These typedefs attempt to ensure consistent 'ticks' handling
2 typedef unsigned long long TIC_t;
3 typedef long long SIC_t;
4
5 // This structure stores a frame's cpu tics used in history
6 // calculations. It exists primarily for SMP support but serves
7 // all environments.
8 typedef struct CPU_t {
9 TIC_t u, n, s, i, w, x, y, z; // as represented in /proc/stat
10 TIC_t u_sav, s_sav, n_sav, i_sav, w_sav, x_sav, y_sav, z_sav; // in the order of our display
11 unsigned id; // the CPU ID number
12 } CPU_t;
每次从/proc/stat取的数据称为一帧的数据,会从到CPU_t结构体的第一行成员里,上次的数据即上一帧的数据就拷到CPU_t的第二排带_sav后缀的成员里,一一对应。
summaryhlp函数里计算我们想看的cpu各详细指标的百分比。只取部分代码或伪码做演示:
1 SIC_t u_frme, s_frme, n_frme, i_frme, w_frme, x_frme, y_frme, z_frme, tot_frme, tz;
2 float scale;
3 u_frme = cpu->u - cpu->u_sav;
4 s_frme = cpu->s - cpu->s_sav;
5
6 tot_frme = u_frme + s_frme + n_frme + i_frme + w_frme + x_frme + y_frme + z_frme;
7 if (tot_frme < 1) tot_frme = 1;
8 scale = 100.0 / (float)tot_frme;
9
10 us% = (float)u_frme * scale;
11 sy% = (float)s_frme * scale;
12
13 cpu->u_sav = cpu->u;
14 cpu->s_sav = cpu->s;
15 每个进程占cpu百分比计算:
1 Frame_tscale = 100.0f / ((float)Hertz * (float)et * (Rc.mode_irixps ? 1 : Cpu_tot));
2 float u = (float)p->pcpu * Frame_tscale;
算的是两帧之间总时间片数量,各进程占的时间片数量百分比。