From c68800726d28f850d148f36cef728bf237aad32b Mon Sep 17 00:00:00 2001 From: Simon Schubert Date: Sat, 24 Feb 2007 14:24:06 +0000 Subject: [PATCH] 1:1 Userland threading stage 4.3/4: Add service functions for the handling of exiting/dead lwps. Rework the exiting code to use these functions. This moves MI code back to MI land. --- sys/kern/kern_exit.c | 107 +++++++++++++++++++------ sys/platform/pc32/i386/pmap.c | 16 +--- sys/platform/pc32/i386/vm_machdep.c | 10 +-- sys/platform/vkernel/i386/vm_machdep.c | 10 +-- sys/platform/vkernel/platform/pmap.c | 15 +--- sys/sys/proc.h | 6 +- sys/vm/pmap.h | 4 +- 7 files changed, 103 insertions(+), 65 deletions(-) diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 603a765c0c..0c56f70f81 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -37,7 +37,7 @@ * * @(#)kern_exit.c 8.7 (Berkeley) 2/12/94 * $FreeBSD: src/sys/kern/kern_exit.c,v 1.92.2.11 2003/01/13 22:51:16 dillon Exp $ - * $DragonFly: src/sys/kern/kern_exit.c,v 1.74 2007/02/21 15:46:48 corecode Exp $ + * $DragonFly: src/sys/kern/kern_exit.c,v 1.75 2007/02/24 14:24:06 corecode Exp $ */ #include "opt_compat.h" @@ -394,7 +394,86 @@ exit1(int rv) * finish. cpu_exit will end with a call to cpu_switch(), finishing * our execution (pun intended). */ - cpu_proc_exit(); + lwp_exit(); +} + +void +lwp_exit(void) +{ +#if notyet + struct lwp *lp = curthread->td_lwp; + struct proc *p = lp->lwp_proc; + + --p->p_nthreads; + wakeup(&p->p_nthreads); +#endif + cpu_lwp_exit(); +} + +/* + * Wait until a lwp is completely dead. + * + * If the thread is still executing, which can't be waited upon, + * return failure. The caller is responsible of waiting a little + * bit and checking again. + * + * Suggested use: + * while (!lwp_wait(lp)) + * tsleep(lp, 0, "lwpwait", 1); + */ +static int +lwp_wait(struct lwp *lp) +{ + struct thread *td = lp->lwp_thread;; + + KKASSERT(lwkt_preempted_proc() != lp); + + while (lp->lwp_lock > 0) + tsleep(lp, 0, "lwpwait1", 1); + + lwkt_wait_free(td); + + /* + * The lwp's thread may still be in the middle + * of switching away, we can't rip its stack out from + * under it until TDF_EXITING is set and both + * TDF_RUNNING and TDF_PREEMPT_LOCK are clear. + * TDF_PREEMPT_LOCK must be checked because TDF_RUNNING + * will be cleared temporarily if a thread gets + * preempted. + * + * YYY no wakeup occurs, so we simply return failure + * and let the caller deal with sleeping and calling + * us again. + */ + if ((td->td_flags & (TDF_RUNNING|TDF_PREEMPT_LOCK|TDF_EXITING)) != + TDF_EXITING) + return (0); + + return (1); +} + +/* + * Release the resources associated with a lwp. + * The lwp must be completely dead. + */ +void +lwp_dispose(struct lwp *lp) +{ + struct thread *td = lp->lwp_thread;; + + KKASSERT(lwkt_preempted_proc() != lp); + KKASSERT(td->td_refs == 0); + KKASSERT((td->td_flags & (TDF_RUNNING|TDF_PREEMPT_LOCK|TDF_EXITING)) == + TDF_EXITING); + + if (td != NULL) { + td->td_proc = NULL; + td->td_lwp = NULL; + lp->lwp_thread = NULL; + lwkt_free_thread(td); + } + zfree(lwp_zone, lp); } int @@ -480,26 +559,9 @@ loop: * At the moment, if this occurs, we are not woken * up and rely on a one-second retry. */ - while (p->p_lock || deadlp->lwp_lock) { - while (deadlp->lwp_lock) - tsleep(deadlp, 0, "reap3l", hz); - while (p->p_lock) - tsleep(p, 0, "reap3", hz); - } - lwkt_wait_free(deadlp->lwp_thread); - - /* - * The process's thread may still be in the middle - * of switching away, we can't rip its stack out from - * under it until TDF_EXITING is set and both - * TDF_RUNNING and TDF_PREEMPT_LOCK are clear. - * TDF_PREEMPT_LOCK must be checked because TDF_RUNNING - * will be cleared temporarily if a thread gets - * preempted. - * - * YYY no wakeup occurs so we depend on the timeout. - */ - if ((deadlp->lwp_thread->td_flags & (TDF_RUNNING|TDF_PREEMPT_LOCK|TDF_EXITING)) != TDF_EXITING) { + while (p->p_lock) + tsleep(p, 0, "reap3", hz); + if (!lwp_wait(deadlp)) { tsleep(deadlp->lwp_thread, 0, "reap2", 1); goto loop; } @@ -566,7 +628,6 @@ loop: } vm_waitproc(p); - zfree(lwp_zone, deadlp); zfree(proc_zone, p); nprocs--; return (0); diff --git a/sys/platform/pc32/i386/pmap.c b/sys/platform/pc32/i386/pmap.c index 766e0ac8cf..9f97f09587 100644 --- a/sys/platform/pc32/i386/pmap.c +++ b/sys/platform/pc32/i386/pmap.c @@ -40,7 +40,7 @@ * * from: @(#)pmap.c 7.7 (Berkeley) 5/12/91 * $FreeBSD: src/sys/i386/i386/pmap.c,v 1.250.2.18 2002/03/06 22:48:53 silby Exp $ - * $DragonFly: src/sys/platform/pc32/i386/pmap.c,v 1.73 2007/02/03 17:05:58 corecode Exp $ + * $DragonFly: src/sys/platform/pc32/i386/pmap.c,v 1.74 2007/02/24 14:24:06 corecode Exp $ */ /* @@ -915,22 +915,14 @@ pmap_init_proc(struct proc *p, struct thread *td) * Dispose the UPAGES for a process that has exited. * This routine directly impacts the exit perf of a process. */ -struct thread * +void pmap_dispose_proc(struct proc *p) { - struct thread *td = NULL; - struct lwp *lp; - KASSERT(p->p_lock == 0, ("attempt to dispose referenced proc! %p", p)); - lp = ONLY_LWP_IN_PROC(p); - if (lp != NULL && (td = lp->lwp_thread) != NULL) { - td->td_proc = NULL; - td->td_lwp = NULL; - lp->lwp_thread = NULL; - } + lwp_dispose(ONLY_LWP_IN_PROC(p)); + p->p_addr = NULL; - return(td); } /*************************************************** diff --git a/sys/platform/pc32/i386/vm_machdep.c b/sys/platform/pc32/i386/vm_machdep.c index 2a163a213e..e163109e78 100644 --- a/sys/platform/pc32/i386/vm_machdep.c +++ b/sys/platform/pc32/i386/vm_machdep.c @@ -39,7 +39,7 @@ * from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91 * Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$ * $FreeBSD: src/sys/i386/i386/vm_machdep.c,v 1.132.2.9 2003/01/25 19:02:23 dillon Exp $ - * $DragonFly: src/sys/platform/pc32/i386/vm_machdep.c,v 1.56 2007/02/03 17:05:58 corecode Exp $ + * $DragonFly: src/sys/platform/pc32/i386/vm_machdep.c,v 1.57 2007/02/24 14:24:06 corecode Exp $ */ #include "use_npx.h" @@ -232,7 +232,7 @@ cpu_set_thread_handler(thread_t td, void (*rfunc)(void), void *func, void *arg) } void -cpu_proc_exit(void) +cpu_lwp_exit(void) { struct thread *td = curthread; struct pcb *pcb; @@ -295,12 +295,8 @@ cpu_thread_exit(void) void cpu_proc_wait(struct proc *p) { - struct thread *td; - /* drop per-process resources */ - td = pmap_dispose_proc(p); - if (td) - lwkt_free_thread(td); + pmap_dispose_proc(p); } #ifdef notyet diff --git a/sys/platform/vkernel/i386/vm_machdep.c b/sys/platform/vkernel/i386/vm_machdep.c index 7ace8b284f..429d79629d 100644 --- a/sys/platform/vkernel/i386/vm_machdep.c +++ b/sys/platform/vkernel/i386/vm_machdep.c @@ -39,7 +39,7 @@ * from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91 * Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$ * $FreeBSD: src/sys/i386/i386/vm_machdep.c,v 1.132.2.9 2003/01/25 19:02:23 dillon Exp $ - * $DragonFly: src/sys/platform/vkernel/i386/vm_machdep.c,v 1.7 2007/02/03 10:30:12 corecode Exp $ + * $DragonFly: src/sys/platform/vkernel/i386/vm_machdep.c,v 1.8 2007/02/24 14:24:06 corecode Exp $ */ #include "use_npx.h" @@ -232,7 +232,7 @@ cpu_set_thread_handler(thread_t td, void (*rfunc)(void), void *func, void *arg) } void -cpu_proc_exit(void) +cpu_lwp_exit(void) { struct thread *td = curthread; struct pcb *pcb; @@ -295,12 +295,8 @@ cpu_thread_exit(void) void cpu_proc_wait(struct proc *p) { - struct thread *td; - /* drop per-process resources */ - td = pmap_dispose_proc(p); - if (td) - lwkt_free_thread(td); + pmap_dispose_proc(p); } #ifdef notyet diff --git a/sys/platform/vkernel/platform/pmap.c b/sys/platform/vkernel/platform/pmap.c index 215b2e9ef5..a409af14a0 100644 --- a/sys/platform/vkernel/platform/pmap.c +++ b/sys/platform/vkernel/platform/pmap.c @@ -38,7 +38,7 @@ * * from: @(#)pmap.c 7.7 (Berkeley) 5/12/91 * $FreeBSD: src/sys/i386/i386/pmap.c,v 1.250.2.18 2002/03/06 22:48:53 silby Exp $ - * $DragonFly: src/sys/platform/vkernel/platform/pmap.c,v 1.16 2007/02/03 17:05:59 corecode Exp $ + * $DragonFly: src/sys/platform/vkernel/platform/pmap.c,v 1.17 2007/02/24 14:24:06 corecode Exp $ */ /* * NOTE: PMAP_INVAL_ADD: In pc32 this function is called prior to adjusting @@ -872,22 +872,13 @@ pmap_init_proc(struct proc *p, struct thread *td) * Destroy the UPAGES for a process that has exited and disassociate * the process from its thread. */ -struct thread * +void pmap_dispose_proc(struct proc *p) { - struct thread *td = NULL; - struct lwp *lp; - KASSERT(p->p_lock == 0, ("attempt to dispose referenced proc! %p", p)); - lp = ONLY_LWP_IN_PROC(p); - if (lp != NULL && (td = lp->lwp_thread) != NULL) { - lp->lwp_thread = NULL; - td->td_lwp = NULL; - td->td_proc = NULL; - } + lwp_dispose(ONLY_LWP_IN_PROC(p)); p->p_addr = NULL; - return(td); } /* diff --git a/sys/sys/proc.h b/sys/sys/proc.h index bc1138919b..6fed6faeb4 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -37,7 +37,7 @@ * * @(#)proc.h 8.15 (Berkeley) 5/19/95 * $FreeBSD: src/sys/sys/proc.h,v 1.99.2.9 2003/06/06 20:21:32 tegge Exp $ - * $DragonFly: src/sys/sys/proc.h,v 1.100 2007/02/21 15:45:37 corecode Exp $ + * $DragonFly: src/sys/sys/proc.h,v 1.101 2007/02/24 14:24:06 corecode Exp $ */ #ifndef _SYS_PROC_H_ @@ -492,8 +492,10 @@ int suser_cred (struct ucred *cred, int flag); void cpu_heavy_switch (struct thread *); void cpu_lwkt_switch (struct thread *); -void cpu_proc_exit (void) __dead2; +void cpu_lwp_exit (void) __dead2; void cpu_thread_exit (void) __dead2; +void lwp_exit (void) __dead2; +void lwp_dispose (struct lwp *); void exit1 (int) __dead2; void cpu_fork (struct lwp *, struct lwp *, int); void cpu_set_fork_handler (struct lwp *, void (*)(void *), void *); diff --git a/sys/vm/pmap.h b/sys/vm/pmap.h index 232bada7c0..79973ca06e 100644 --- a/sys/vm/pmap.h +++ b/sys/vm/pmap.h @@ -62,7 +62,7 @@ * rights to redistribute these changes. * * $FreeBSD: src/sys/vm/pmap.h,v 1.33.2.4 2002/03/06 22:44:24 silby Exp $ - * $DragonFly: src/sys/vm/pmap.h,v 1.22 2007/01/11 10:39:41 dillon Exp $ + * $DragonFly: src/sys/vm/pmap.h,v 1.23 2007/02/24 14:24:06 corecode Exp $ */ /* @@ -167,7 +167,7 @@ void pmap_prefault (pmap_t, vm_offset_t, vm_map_entry_t); int pmap_mincore (pmap_t pmap, vm_offset_t addr); void pmap_init_proc (struct proc *p, struct thread *td); void pmap_init_thread (struct thread *td); -struct thread *pmap_dispose_proc (struct proc *p); +void pmap_dispose_proc (struct proc *p); void pmap_activate (struct proc *p); void pmap_deactivate (struct proc *p); vm_offset_t pmap_addr_hint (vm_object_t obj, vm_offset_t addr, vm_size_t size); -- 2.41.0