先来看,p->utime和p->stime分别是update_processtime里打点得到的用户态、内核态次数,是计算cpu利用率的关键。
if (hardirq_count() - hardirq_offset || (p->flags & PF_HARDIRQ)) cpustat->irq = cputime64_add(cpustat->irq, tmp); else if (softirq_count() || (p->flags & PF_SOFTIRQ)) cpustat->softirq = cputime64_add(cpustat->softirq, tmp); else if (p != rq->idle) { cpustat->system = cputime64_add(cpustat->system, tmp); cpuacct_charge(p, cputime); } else if (atomic_read(&rq->nr_iowait) > 0) cpustat->iowait = cputime64_add(cpustat->iowait, tmp); else cpustat->idle = cputime64_add(cpustat->idle, tmp); /* Account for system time used */ acct_update_integrals(p);如果被时钟中断打断时进程处于用户态,则累加此次tick到p->user, 如果p的nice比较好,则将其加到cpu的
再提出一个概念,反应到/proc/stat或者/proc/pid/stat中的运行时间,都是clock_t单位。
也就是说,都是用户tick数。什么是用户tick数?假设USER_HZ为100,那么1秒中来的用户tick数就应该是10个。
具体应用场景是,在规定时间内,假设进程执行了sum_exec_runtime毫秒,那么用户态就应该经历了sum_exec_runtime/10
个tick。
1)将p->utime,p->stime转换为clock_t单位的utime。
2)然后通过将p->se.sum_exec_runtime纳秒转换成以USER_HZ(一般为100)为单位的tick数(即clock_t)。
3)根据utime和total的比例,算出实际进程的进程时间(还是clock_t单位)
实际上,个人觉得,第1步没有必要将其转换为clock_t格式,而直接算比例就可以了。
clock_t task_utime(struct task_struct *p) { clock_t utime = cputime_to_clock_t(p->utime), total = utime + cputime_to_clock_t(p->stime); u64 temp; /* * Use CFS's precise accounting: */ temp = (u64)nsec_to_clock_t(p->se.sum_exec_runtime); if (total) { temp *= utime; do_div(temp, total); } utime = (clock_t)temp; p->prev_utime = max(p->prev_utime, clock_t_to_cputime(utime)); return cputime_to_clock_t(p->prev_utime); }