マルチCPU(補足)
Rev.1を表示中。最新版はこちら。
先のマルチCPUの記載で、プロセスの実行しているCPU ID取得のユーザ空間での実装がされてないとの認識でしたが、さらにCPU IDの検証をしましたら、スペースを区切りとするプロセス状態を表示する/proc/self/statの38項目に実装されていました。(cutの-f39は取得項目の末尾がスペースとなる項目です。)[root@localhost ~]# cat /proc/self/stat | cut -d ' ' -f39 0 [root@localhost ~]# cat /proc/self/stat | cut -d ' ' -f39 0 [root@localhost ~]# cat /proc/self/stat | cut -d ' ' -f39 1 [root@localhost ~]# cat /proc/self/stat | cut -d ' ' -f39 1 [root@localhost ~]# cat /proc/self/stat | cut -d ' ' -f39 1 [root@localhost ~]# cat /proc/self/stat | cut -d ' ' -f39 0 [root@localhost ~]# cat /proc/self/stat | cut -d ' ' -f39 1 [root@localhost ~]# cat /proc/self/stat | cut -d ' ' -f39 1 [root@localhost ~]# cat /proc/self/stat | cut -d ' ' -f39 0 [root@localhost ~]# cat /proc/self/stat | cut -d ' ' -f39/proc/tid/statのコールバックです。selfはcurrentで、tidにより起動済み任意プロセスのCPU IDも確認できます。
int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns, struct pid *pid, struct task_struct *task) { return do_task_stat(m, ns, pid, task, 0); } static int do_task_stat(struct seq_file *m, struct pid_namespace *ns, struct pid *pid, struct task_struct *task, int whole) { unsigned long vsize, eip, esp, wchan = ~0UL; long priority, nice; int tty_pgrp = -1, tty_nr = 0; sigset_t sigign, sigcatch; char state; pid_t ppid = 0, pgid = -1, sid = -1; int num_threads = 0; int permitted; struct mm_struct *mm; unsigned long long start_time; unsigned long cmin_flt = 0, cmaj_flt = 0; unsigned long min_flt = 0, maj_flt = 0; cputime_t cutime, cstime, utime, stime; cputime_t cgtime, gtime; unsigned long rsslim = 0; char tcomm[sizeof(task->comm)]; unsigned long flags; state = *get_task_state(task); vsize = eip = esp = 0; permitted = ptrace_may_access(task, PTRACE_MODE_READ | PTRACE_MODE_NOAUDIT); mm = get_task_mm(task); if (mm) { vsize = task_vsize(mm); if (permitted) { eip = KSTK_EIP(task); esp = KSTK_ESP(task); } } get_task_comm(tcomm, task); sigemptyset(&sigign); sigemptyset(&sigcatch); cutime = cstime = utime = stime = 0; cgtime = gtime = 0; if (lock_task_sighand(task, &flags)) { struct signal_struct *sig = task->signal; if (sig->tty) { struct pid *pgrp = tty_get_pgrp(sig->tty); tty_pgrp = pid_nr_ns(pgrp, ns); put_pid(pgrp); tty_nr = new_encode_dev(tty_devnum(sig->tty)); } num_threads = get_nr_threads(task); collect_sigign_sigcatch(task, &sigign, &sigcatch); cmin_flt = sig->cmin_flt; cmaj_flt = sig->cmaj_flt; cutime = sig->cutime; cstime = sig->cstime; cgtime = sig->cgtime; rsslim = ACCESS_ONCE(sig->rlim[RLIMIT_RSS].rlim_cur); if (whole) { struct task_struct *t = task; do { min_flt += t->min_flt; maj_flt += t->maj_flt; gtime += t->gtime; t = next_thread(t); } while (t != task); min_flt += sig->min_flt; maj_flt += sig->maj_flt; thread_group_times(task, &utime, &stime); gtime += sig->gtime; } sid = task_session_nr_ns(task, ns); ppid = task_tgid_nr_ns(task->real_parent, ns); pgid = task_pgrp_nr_ns(task, ns); unlock_task_sighand(task, &flags); } if (permitted && (!whole || num_threads < 2)) wchan = get_wchan(task); if (!whole) { min_flt = task->min_flt; maj_flt = task->maj_flt; task_times(task, &utime, &stime); gtime = task->gtime; } priority = task_prio(task); nice = task_nice(task); start_time = (unsigned long long)task->real_start_time.tv_sec * NSEC_PER_SEC + task->real_start_time.tv_nsec; start_time = nsec_to_clock_t(start_time); seq_printf(m, "%d (%s) %c %d %d %d %d %d %u %lu \ %lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \ %lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu %lu %ld %lu %lu %lu\n", pid_nr_ns(pid, ns), tcomm, state, ppid, pgid, sid, tty_nr, tty_pgrp, task->flags, min_flt, cmin_flt, maj_flt, cmaj_flt, cputime_to_clock_t(utime), cputime_to_clock_t(stime), cputime_to_clock_t(cutime), cputime_to_clock_t(cstime), priority, nice, num_threads, start_time, vsize, mm ? get_mm_rss(mm) : 0, rsslim, mm ? (permitted ? mm->start_code : 1) : 0, mm ? (permitted ? mm->end_code : 1) : 0, (permitted && mm) ? mm->start_stack : 0, esp, task->pending.signal.sig[0] & 0x7fffffffUL, task->blocked.sig[0] & 0x7fffffffUL, sigign .sig[0] & 0x7fffffffUL, sigcatch .sig[0] & 0x7fffffffUL, wchan, 0UL, 0UL, task->exit_signal, task_cpu(task), <---------------------------- CPU ID task->rt_priority, task->policy, (unsigned long long)delayacct_blkio_ticks(task), cputime_to_clock_t(gtime), cputime_to_clock_t(cgtime), (mm && permitted) ? mm->start_data : 0, (mm && permitted) ? mm->end_data : 0, (mm && permitted) ? mm->start_brk : 0); if (mm) mmput(mm); return 0; } static inline unsigned int task_cpu(const struct task_struct *p) { return task_thread_info(p)->cpu; }