/* * Clean out CPU timers still ticking when a thread exited. The task * pointer is cleared, and the expiry time is replaced with the residual * time for later timer_gettime calls to return. * This must be called with the siglock held. */ static void cleanup_timers(struct list_head *head, cputime_t utime, cputime_t stime, unsigned long long sum_exec_runtime) { cputime_t ptime = utime + stime; cleanup_timers_list(head, cputime_to_expires(ptime)); cleanup_timers_list(++head, cputime_to_expires(utime)); cleanup_timers_list(++head, sum_exec_runtime); }
static inline unsigned long long virt_ticks(struct task_struct *p) { cputime_t utime, stime; task_cputime(p, &utime, &stime); return cputime_to_expires(utime); }
/* * Sample a process (thread group) timer for the given group_leader task. * Must be called with task sighand lock held for safe while_each_thread() * traversal. */ static int cpu_timer_sample_group(const clockid_t which_clock, struct task_struct *p, unsigned long long *sample) { struct task_cputime cputime; thread_group_cputimer(p, &cputime); switch (CPUCLOCK_WHICH(which_clock)) { default: return -EINVAL; case CPUCLOCK_PROF: *sample = cputime_to_expires(cputime.utime + cputime.stime); break; case CPUCLOCK_VIRT: *sample = cputime_to_expires(cputime.utime); break; case CPUCLOCK_SCHED: *sample = cputime.sum_exec_runtime; break; } return 0; }
static inline unsigned long long timespec_to_sample(const clockid_t which_clock, const struct timespec *tp) { unsigned long long ret; ret = 0; /* high half always zero when .cpu used */ if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) { ret = (unsigned long long)tp->tv_sec * NSEC_PER_SEC + tp->tv_nsec; } else { ret = cputime_to_expires(timespec_to_cputime(tp)); } return ret; }