プロセスがユーザーモードで使用した時間とは
はてなのnaoyaさんの負荷とは何かを読んで大変勉強になりました。でCPU 使用率でプロセスがユーザーモードで使用した時間をjiffies_to_cputimeで取得しているようです。色々なタイミングでプロセスが切り替わるのを、どのようにしてCPU使用時間を取得するのか気になりました。
それをカレントプロセスにただ使用時間として足しこんでいるだけです。要はaccount_process_tickが呼ばれた時点(タイマー割り込みが発生した時点)で、タイマー発生にかかる時間はそのプロセスが使用していたものとして処理しているようです。
完全にタイムスライスで動作しているわけでなく、割り込みとかシステムコール等プロセスのスイッチングいろいろ想定されるわけで、ユーザーモードで使用した時間というのは厳密なものでなさそうです。
void update_process_times(int user_tick) { struct task_struct *p = current; int cpu = smp_processor_id(); /* Note: this timer irq context must be accounted for as well. */ account_process_tick(p, user_tick);
void account_process_tick(struct task_struct *p, int user_tick) { cputime_t one_jiffy = jiffies_to_cputime(1); if (user_tick) { account_user_time(p, one_jiffy);jiffies_to_cputimeにはいくつかのバリエーションがあるようですが、この場合__jifは1で呼ばれています。それをただ単に割り込みタイマーの周期CONFIG_HZで割っているようです。
#define NSEC_PER_SEC 1000000000L #define HZ CONFIG_HZ #define jiffies_to_cputime(__jif) ((__jif) * (NSEC_PER_SEC / HZ))CONFIG_HZは.configでカーネルをコンパイルするときに設定するもので、1秒間に何回タイマー割り込みが処理されるかを意味しており、デフォルトは250の4ミリ秒周期になります。NSEC_PER_SECはただ桁調整のためだけのようです。バリエーションによっては1000000とか1とかのものがありました。
それをカレントプロセスにただ使用時間として足しこんでいるだけです。要はaccount_process_tickが呼ばれた時点(タイマー割り込みが発生した時点)で、タイマー発生にかかる時間はそのプロセスが使用していたものとして処理しているようです。
完全にタイムスライスで動作しているわけでなく、割り込みとかシステムコール等プロセスのスイッチングいろいろ想定されるわけで、ユーザーモードで使用した時間というのは厳密なものでなさそうです。