add RUSAGE_THREAD

Add the RUSAGE_THREAD option for the getrusage system call.  This is
essentially Roland's patch from http://lkml.org/lkml/2008/1/18/589, but the
line about RUSAGE_LWP line has been removed, as suggested by Ulrich and
Christoph.

Signed-off-by: Roland McGrath <roland@redhat.com>
Signed-off-by: Sripathi Kodi <sripathik@in.ibm.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Michael Kerrisk <mtk.manpages@googlemail.com>
Cc: Ulrich Drepper <drepper@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Sripathi Kodi 2008-04-29 00:58:42 -07:00 committed by Linus Torvalds
parent e5949050f2
commit 679c9cd4ac
2 changed files with 23 additions and 9 deletions

View file

@ -19,6 +19,7 @@ struct task_struct;
#define RUSAGE_SELF 0 #define RUSAGE_SELF 0
#define RUSAGE_CHILDREN (-1) #define RUSAGE_CHILDREN (-1)
#define RUSAGE_BOTH (-2) /* sys_wait4() uses this */ #define RUSAGE_BOTH (-2) /* sys_wait4() uses this */
#define RUSAGE_THREAD 1 /* only the calling thread */
struct rusage { struct rusage {
struct timeval ru_utime; /* user time used */ struct timeval ru_utime; /* user time used */

View file

@ -1545,6 +1545,19 @@ out:
* *
*/ */
static void accumulate_thread_rusage(struct task_struct *t, struct rusage *r,
cputime_t *utimep, cputime_t *stimep)
{
*utimep = cputime_add(*utimep, t->utime);
*stimep = cputime_add(*stimep, t->stime);
r->ru_nvcsw += t->nvcsw;
r->ru_nivcsw += t->nivcsw;
r->ru_minflt += t->min_flt;
r->ru_majflt += t->maj_flt;
r->ru_inblock += task_io_get_inblock(t);
r->ru_oublock += task_io_get_oublock(t);
}
static void k_getrusage(struct task_struct *p, int who, struct rusage *r) static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
{ {
struct task_struct *t; struct task_struct *t;
@ -1554,6 +1567,11 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
memset((char *) r, 0, sizeof *r); memset((char *) r, 0, sizeof *r);
utime = stime = cputime_zero; utime = stime = cputime_zero;
if (who == RUSAGE_THREAD) {
accumulate_thread_rusage(p, r, &utime, &stime);
goto out;
}
rcu_read_lock(); rcu_read_lock();
if (!lock_task_sighand(p, &flags)) { if (!lock_task_sighand(p, &flags)) {
rcu_read_unlock(); rcu_read_unlock();
@ -1586,14 +1604,7 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
r->ru_oublock += p->signal->oublock; r->ru_oublock += p->signal->oublock;
t = p; t = p;
do { do {
utime = cputime_add(utime, t->utime); accumulate_thread_rusage(t, r, &utime, &stime);
stime = cputime_add(stime, t->stime);
r->ru_nvcsw += t->nvcsw;
r->ru_nivcsw += t->nivcsw;
r->ru_minflt += t->min_flt;
r->ru_majflt += t->maj_flt;
r->ru_inblock += task_io_get_inblock(t);
r->ru_oublock += task_io_get_oublock(t);
t = next_thread(t); t = next_thread(t);
} while (t != p); } while (t != p);
break; break;
@ -1605,6 +1616,7 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
unlock_task_sighand(p, &flags); unlock_task_sighand(p, &flags);
rcu_read_unlock(); rcu_read_unlock();
out:
cputime_to_timeval(utime, &r->ru_utime); cputime_to_timeval(utime, &r->ru_utime);
cputime_to_timeval(stime, &r->ru_stime); cputime_to_timeval(stime, &r->ru_stime);
} }
@ -1618,7 +1630,8 @@ int getrusage(struct task_struct *p, int who, struct rusage __user *ru)
asmlinkage long sys_getrusage(int who, struct rusage __user *ru) asmlinkage long sys_getrusage(int who, struct rusage __user *ru)
{ {
if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN) if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN &&
who != RUSAGE_THREAD)
return -EINVAL; return -EINVAL;
return getrusage(current, who, ru); return getrusage(current, who, ru);
} }