|
@@ -260,30 +260,43 @@ static int cpu_clock_sample_group(const clockid_t which_clock,
|
|
|
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 {
|
|
|
+ read_lock(&tasklist_lock);
|
|
|
+
|
|
|
+ if (tsk->sighand && (tsk == current || thread_group_leader(tsk)))
|
|
|
+ err = cpu_clock_sample_group(which_clock, tsk, &rtn);
|
|
|
+
|
|
|
+ read_unlock(&tasklist_lock);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!err)
|
|
|
+ sample_to_timespec(which_clock, rtn, tp);
|
|
|
+
|
|
|
+ return err;
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
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;
|
|
|
+ int err = -EINVAL;
|
|
|
|
|
|
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);
|
|
|
- }
|
|
|
+ err = posix_cpu_clock_get_task(current, which_clock, tp);
|
|
|
} else {
|
|
|
/*
|
|
|
* Find the given PID, and validate that the caller
|
|
@@ -292,29 +305,12 @@ static int posix_cpu_clock_get(const clockid_t which_clock, struct timespec *tp)
|
|
|
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);
|
|
|
- }
|
|
|
- }
|
|
|
+ if (p)
|
|
|
+ err = posix_cpu_clock_get_task(p, which_clock, tp);
|
|
|
rcu_read_unlock();
|
|
|
}
|
|
|
|
|
|
- if (error)
|
|
|
- return error;
|
|
|
- sample_to_timespec(which_clock, rtn, tp);
|
|
|
- return 0;
|
|
|
+ return err;
|
|
|
}
|
|
|
|
|
|
|