summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2004-08-30 20:35:38 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-08-30 20:35:38 -0700
commit497c9d6819e984f737ff51489258f213e193d52e (patch)
tree654e9b23075a0050a17ce7dfc877ea94f95f7e60 /include/linux
parentca3f74aa7baa11482435275c41ba323e3e2ec7b6 (diff)
[PATCH] fix rusage semantics
This patch changes the rusage bookkeeping and the semantics of the getrusage and times calls in a couple of ways. The first change is in the c* fields counting dead child processes. POSIX requires that children that have died be counted in these fields when they are reaped by a wait* call, and that if they are never reaped (e.g. because of ignoring SIGCHLD, or exitting yourself first) then they are never counted. These were counted in release_task for all threads. I've changed it so they are counted in wait_task_zombie, i.e. exactly when being reaped. POSIX also specifies for RUSAGE_CHILDREN that the report include the reaped child processes of the calling process, i.e. whole thread group in Linux, not just ones forked by the calling thread. POSIX specifies tms_c[us]time fields in the times call the same way. I've moved the c* fields that contain this information into signal_struct, where the single set of counters accumulates data from any thread in the group that calls wait*. Finally, POSIX specifies getrusage and times as returning cumulative totals for the whole process (aka thread group), not just the calling thread. I've added fields in signal_struct to accumulate the stats of detached threads as they die. The process stats are the sums of these records plus the stats of remaining each live/zombie thread. The times and getrusage calls, and the internal uses for filling in wait4 results and siginfo_t, now iterate over the threads in the thread group and sum up their stats along with the stats recorded for threads already dead and gone. I added a new value RUSAGE_GROUP (-3) for the getrusage system call rather than changing the behavior of the old RUSAGE_SELF (0). POSIX specifies RUSAGE_SELF to mean all threads, so the glibc getrusage call will just translate it to RUSAGE_GROUP for new kernels. I did this thinking that someone somewhere might want the old behavior with an old glibc and a new kernel (it is only different if they are using CLONE_THREAD anyway). However, I've changed the times system call to conform to POSIX as well and did not provide any backward compatibility there. In that case there is nothing easy like a parameter value to use, it would have to be a new system call number. That seems pretty pointless. Given that, I wonder if it is worth bothering to preserve the compatible RUSAGE_SELF behavior by introducing RUSAGE_GROUP instead of just changing RUSAGE_SELF's meaning. Comments? I've done some basic testing on x86 and x86-64, and all the numbers come out right after these fixes. (I have a test program that shows a few Signed-off-by: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/resource.h1
-rw-r--r--include/linux/sched.h16
2 files changed, 14 insertions, 3 deletions
diff --git a/include/linux/resource.h b/include/linux/resource.h
index 21a86cb6acdb..3c848324df44 100644
--- a/include/linux/resource.h
+++ b/include/linux/resource.h
@@ -17,6 +17,7 @@
#define RUSAGE_SELF 0
#define RUSAGE_CHILDREN (-1)
#define RUSAGE_BOTH (-2) /* sys_wait4() uses this */
+#define RUSAGE_GROUP (-3) /* thread group sum + dead threads */
struct rusage {
struct timeval ru_utime; /* user time used */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index f89a32a4bf48..3aaf8e5f2216 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -301,6 +301,16 @@ struct signal_struct {
int leader;
struct tty_struct *tty; /* NULL if no tty */
+
+ /*
+ * Cumulative resource counters for dead threads in the group,
+ * and for reaped dead child processes forked by this group.
+ * Live threads maintain their own counters and add to these
+ * in __exit_signal, except for the group leader.
+ */
+ unsigned long utime, stime, cutime, cstime;
+ unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw;
+ unsigned long min_flt, maj_flt, cmin_flt, cmaj_flt;
};
/*
@@ -495,11 +505,11 @@ struct task_struct {
unsigned long it_real_value, it_prof_value, it_virt_value;
unsigned long it_real_incr, it_prof_incr, it_virt_incr;
struct timer_list real_timer;
- unsigned long utime, stime, cutime, cstime;
- unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw; /* context switch counts */
+ unsigned long utime, stime;
+ unsigned long nvcsw, nivcsw; /* context switch counts */
u64 start_time;
/* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */
- unsigned long min_flt, maj_flt, cmin_flt, cmaj_flt;
+ unsigned long min_flt, maj_flt;
/* process credentials */
uid_t uid,euid,suid,fsuid;
gid_t gid,egid,sgid,fsgid;