static int posix_cpu_clock_get(const clockid_t which_clock, struct timespec *tp) { const pid_t pid = CPUCLOCK_PID(which_clock); int error = -EINVAL; unsigned long long rtn; if (pid == 0) { /* * Special case constant value for our own clocks. * We don't have to do any lookup to find ourselves. */ if (CPUCLOCK_PERTHREAD(which_clock)) { /* * Sampling just ourselves we can do with no locking. */ error = cpu_clock_sample(which_clock, current, &rtn); } else { read_lock(&tasklist_lock); error = cpu_clock_sample_group(which_clock, current, &rtn); read_unlock(&tasklist_lock); } } else { /* * Find the given PID, and validate that the caller * should be able to see it. */ struct task_struct *p; rcu_read_lock(); p = find_task_by_vpid(pid); if (p) { if (CPUCLOCK_PERTHREAD(which_clock)) { if (same_thread_group(p, current)) { error = cpu_clock_sample(which_clock, p, &rtn); } } else { read_lock(&tasklist_lock); if (thread_group_leader(p) && p->sighand) { error = cpu_clock_sample_group(which_clock, p, &rtn); } read_unlock(&tasklist_lock); } } rcu_read_unlock(); } if (error) return error; sample_to_timespec(which_clock, rtn, tp); return 0; }
static int posix_cpu_clock_get_task(struct task_struct *tsk, const clockid_t which_clock, struct timespec *tp) { int err = -EINVAL; unsigned long long rtn; if (CPUCLOCK_PERTHREAD(which_clock)) { if (same_thread_group(tsk, current)) err = cpu_clock_sample(which_clock, tsk, &rtn); } else { unsigned long flags; struct sighand_struct *sighand; /* * while_each_thread() is not yet entirely RCU safe, * keep locking the group while sampling process * clock for now. */ sighand = lock_task_sighand(tsk, &flags); if (!sighand) return err; if (tsk == current || thread_group_leader(tsk)) err = cpu_clock_sample_group(which_clock, tsk, &rtn); unlock_task_sighand(tsk, &flags); } if (!err) sample_to_timespec(which_clock, rtn, tp); return err; }
static int posix_cpu_clock_get_task(struct task_struct *tsk, const clockid_t which_clock, struct timespec *tp) { int err = -EINVAL; unsigned long long rtn; if (CPUCLOCK_PERTHREAD(which_clock)) { if (same_thread_group(tsk, current)) err = cpu_clock_sample(which_clock, tsk, &rtn); } else { if (tsk == current || thread_group_leader(tsk)) err = cpu_clock_sample_group(which_clock, tsk, &rtn); } if (!err) sample_to_timespec(which_clock, rtn, tp); return err; }