summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_exit.c
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2007-06-01 01:12:45 +0000
committerjeff <jeff@FreeBSD.org>2007-06-01 01:12:45 +0000
commita7a8bac81f171b93c4770f51c694b15c84a2f9f8 (patch)
tree9c09dcc76185c3dc30b048a5f2eb972f3bb8a849 /sys/kern/kern_exit.c
parent062ed7352f59fb6db93a3f51ca6e64ec0cefca22 (diff)
downloadFreeBSD-src-a7a8bac81f171b93c4770f51c694b15c84a2f9f8.zip
FreeBSD-src-a7a8bac81f171b93c4770f51c694b15c84a2f9f8.tar.gz
- Move rusage from being per-process in struct pstats to per-thread in
td_ru. This removes the requirement for per-process synchronization in statclock() and mi_switch(). This was previously supported by sched_lock which is going away. All modifications to rusage are now done in the context of the owning thread. reads proceed without locks. - Aggregate exiting threads rusage in thread_exit() such that the exiting thread's rusage is not lost. - Provide a new routine, rufetch() to fetch an aggregate of all rusage structures from all threads in a process. This routine must be used in any place requiring a rusage from a process prior to it's exit. The exited process's rusage is still available via p_ru. - Aggregate tick statistics only on demand via rufetch() or when a thread exits. Tick statistics are kept in the thread and protected by sched_lock until it exits. Initial patch by: attilio Reviewed by: attilio, bde (some objections), arch (mostly silent)
Diffstat (limited to 'sys/kern/kern_exit.c')
-rw-r--r--sys/kern/kern_exit.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 029fe3a..54ac392 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -116,6 +116,7 @@ exit1(struct thread *td, int rv)
struct ucred *tracecred;
#endif
struct plimit *plim;
+ struct rusage *ru;
int locked;
/*
@@ -169,7 +170,8 @@ retry:
* Threading support has been turned off.
*/
}
-
+ KASSERT(p->p_numthreads == 1,
+ ("exit1: proc %p exiting with %d threads", p, p->p_numthreads));
/*
* Wakeup anyone in procfs' PIOCWAIT. They should have a hold
* on our vmspace, so we should block below until they have
@@ -195,6 +197,8 @@ retry:
msleep(&p->p_lock, &p->p_mtx, PWAIT, "exithold", 0);
PROC_UNLOCK(p);
+ /* Drain the limit callout while we don't have the proc locked */
+ callout_drain(&p->p_limco);
#ifdef AUDIT
/*
@@ -229,7 +233,7 @@ retry:
*/
EVENTHANDLER_INVOKE(process_exit, p);
- MALLOC(p->p_ru, struct rusage *, sizeof(struct rusage),
+ MALLOC(ru, struct rusage *, sizeof(struct rusage),
M_ZOMBIE, M_WAITOK);
/*
* If parent is waiting for us to exit or exec,
@@ -438,16 +442,20 @@ retry:
PROC_UNLOCK(q);
}
- /*
- * Save exit status and finalize rusage info except for times,
- * adding in child rusage info later when our time is locked.
- */
+ /* Save exit status. */
PROC_LOCK(p);
p->p_xstat = rv;
p->p_xthread = td;
- p->p_stats->p_ru.ru_nvcsw++;
- *p->p_ru = p->p_stats->p_ru;
-
+ /*
+ * All statistics have been aggregated into the final td_ru by
+ * thread_exit(). Copy these into the proc here where wait*()
+ * can find them.
+ * XXX We will miss any statistics gathered between here and
+ * thread_exit() except for those related to clock ticks.
+ */
+ *ru = td->td_ru;
+ ru->ru_nvcsw++;
+ p->p_ru = ru;
/*
* Notify interested parties of our demise.
*/
OpenPOWER on IntegriCloud