mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-23 17:34:00 +03:00
bootchart: Account CPU time spent in non-main threads of processes (v5)
Fix for issue https://github.com/systemd/systemd/issues/139 - Implement fixes suggested by @teg to -v2 - Implement fixes suggested by @zonque to -v3 and -v4
This commit is contained in:
parent
9ebdb1e057
commit
caa4339784
@ -115,6 +115,7 @@ int log_sample(DIR *proc,
|
||||
struct list_sample_data *sampledata;
|
||||
struct ps_sched_struct *ps_prev = NULL;
|
||||
int procfd;
|
||||
int taskfd = -1;
|
||||
|
||||
sampledata = *ptr;
|
||||
|
||||
@ -409,6 +410,63 @@ schedstat_next:
|
||||
ps->total = (ps->last->runtime - ps->first->runtime)
|
||||
/ 1000000000.0;
|
||||
|
||||
/* Take into account CPU runtime/waittime spent in non-main threads of the process
|
||||
* by parsing "/proc/[pid]/task/[tid]/schedstat" for all [tid] != [pid]
|
||||
* See https://github.com/systemd/systemd/issues/139
|
||||
*/
|
||||
|
||||
/* Browse directory "/proc/[pid]/task" to know the thread ids of process [pid] */
|
||||
snprintf(filename, sizeof(filename), PID_FMT "/task", pid);
|
||||
taskfd = openat(procfd, filename, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
|
||||
if (taskfd >= 0) {
|
||||
_cleanup_closedir_ DIR *taskdir = NULL;
|
||||
|
||||
taskdir = fdopendir(taskfd);
|
||||
if (!taskdir) {
|
||||
safe_close(taskfd);
|
||||
return -errno;
|
||||
}
|
||||
FOREACH_DIRENT(ent, taskdir, break) {
|
||||
int r;
|
||||
int tid = -1;
|
||||
_cleanup_close_ int tid_schedstat = -1;
|
||||
long long delta_rt;
|
||||
long long delta_wt;
|
||||
|
||||
if ((ent->d_name[0] < '0') || (ent->d_name[0] > '9'))
|
||||
continue;
|
||||
|
||||
/* Skip main thread as it was already accounted */
|
||||
r = safe_atoi(ent->d_name, &tid);
|
||||
if (r < 0 || tid == pid)
|
||||
continue;
|
||||
|
||||
/* Parse "/proc/[pid]/task/[tid]/schedstat" */
|
||||
snprintf(filename, sizeof(filename), PID_FMT "/schedstat", tid);
|
||||
tid_schedstat = openat(taskfd, filename, O_RDONLY|O_CLOEXEC);
|
||||
|
||||
if (tid_schedstat == -1)
|
||||
continue;
|
||||
|
||||
s = pread(tid_schedstat, buf, sizeof(buf) - 1, 0);
|
||||
if (s <= 0)
|
||||
continue;
|
||||
buf[s] = '\0';
|
||||
|
||||
if (!sscanf(buf, "%s %s %*s", rt, wt))
|
||||
continue;
|
||||
|
||||
r = safe_atolli(rt, &delta_rt);
|
||||
if (r < 0)
|
||||
continue;
|
||||
r = safe_atolli(rt, &delta_wt);
|
||||
if (r < 0)
|
||||
continue;
|
||||
ps->sample->runtime += delta_rt;
|
||||
ps->sample->waittime += delta_wt;
|
||||
}
|
||||
}
|
||||
|
||||
if (!arg_pss)
|
||||
goto catch_rename;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user