Module Name: src Committed By: matt Date: Sun Feb 20 07:04:15 UTC 2011
Modified Files: src/sys/kern [matt-nb5-pq3]: kern_kthread.c src/sys/sys [matt-nb5-pq3]: kthread.h Log Message: Pullup http://mail-index.netbsd.org/source-changes/2010/05/11/msg009810.html to this branch because the new flash framework will need it. To generate a diff of this commit: cvs rdiff -u -r1.24.10.2 -r1.24.10.2.8.1 src/sys/kern/kern_kthread.c cvs rdiff -u -r1.7.10.1 -r1.7.10.1.8.1 src/sys/sys/kthread.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/kern_kthread.c diff -u src/sys/kern/kern_kthread.c:1.24.10.2 src/sys/kern/kern_kthread.c:1.24.10.2.8.1 --- src/sys/kern/kern_kthread.c:1.24.10.2 Mon Feb 2 22:02:24 2009 +++ src/sys/kern/kern_kthread.c Sun Feb 20 07:04:15 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_kthread.c,v 1.24.10.2 2009/02/02 22:02:24 snj Exp $ */ +/* $NetBSD: kern_kthread.c,v 1.24.10.2.8.1 2011/02/20 07:04:15 matt Exp $ */ /*- * Copyright (c) 1998, 1999, 2007, 2009 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_kthread.c,v 1.24.10.2 2009/02/02 22:02:24 snj Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_kthread.c,v 1.24.10.2.8.1 2011/02/20 07:04:15 matt Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -52,6 +52,12 @@ /* * Fork a kernel thread. Any process can request this to be done. + * + * With joinable kthreads KTHREAD_JOINABLE flag this should be known. + * 1. If you specify KTHREAD_JOINABLE, you must call kthread_join() to reap the thread. + * It will not be automatically reaped by the system. + * 2. For any given call to kthread_create(KTHREAD_JOINABLE), you may call kthread_join() + * only once on the returned lwp_t *. */ int kthread_create(pri_t pri, int flag, struct cpu_info *ci, @@ -61,9 +67,10 @@ lwp_t *l; vaddr_t uaddr; bool inmem; - int error; + int error, lc, lwp_flags; va_list ap; - int lc; + + lwp_flags = LWP_DETACHED; inmem = uvm_uarea_alloc(&uaddr); if (uaddr == 0) @@ -73,7 +80,10 @@ } else { lc = SCHED_RR; } - error = lwp_create(&lwp0, &proc0, uaddr, inmem, LWP_DETACHED, NULL, + if ((flag & KTHREAD_JOINABLE) != 0) { + lwp_flags &= ~LWP_DETACHED; + } + error = lwp_create(&lwp0, &proc0, uaddr, inmem, lwp_flags, NULL, 0, func, arg, &l, lc); if (error) { uvm_uarea_free(uaddr, curcpu()); @@ -83,7 +93,7 @@ if (fmt != NULL) { l->l_name = kmem_alloc(MAXCOMLEN, KM_SLEEP); if (l->l_name == NULL) { - lwp_exit(l); + kthread_destroy(l); return ENOMEM; } va_start(ap, fmt); @@ -98,6 +108,11 @@ KASSERT((flag & KTHREAD_MPSAFE) != 0); } + /* Joinable kthread can't be NULL. */ + if ((flag & KTHREAD_JOINABLE) != 0) { + KASSERT(l != NULL); + } + if (pri == PRI_NONE) { if ((flag & KTHREAD_TS) != 0) { /* Maximum user priority level. */ @@ -183,9 +198,39 @@ void kthread_destroy(lwp_t *l) { - + proc_t *p; + KASSERT((l->l_flag & LW_SYSTEM) != 0); KASSERT(l->l_stat == LSIDL); + p = l->l_proc; + + /* Add LRP_DETACHED flag because we can have joinable kthread now. */ + mutex_enter(p->p_lock); + l->l_prflag |= LPR_DETACHED; + mutex_exit(p->p_lock); + lwp_exit(l); } + +/* + * Wait for a kthread to exit, as pthread_join(). + */ +int +kthread_join(lwp_t *l) +{ + lwpid_t departed; + proc_t *p; + int error; + + KASSERT((l->l_flag & LW_SYSTEM) != 0); + KASSERT((l->l_prflag & LPR_DETACHED) == 0); + + p = l->l_proc; + + mutex_enter(p->p_lock); + error = lwp_wait1(curlwp, l->l_lid, &departed, LWPWAIT_EXITCONTROL); + mutex_exit(p->p_lock); + + return error; +} Index: src/sys/sys/kthread.h diff -u src/sys/sys/kthread.h:1.7.10.1 src/sys/sys/kthread.h:1.7.10.1.8.1 --- src/sys/sys/kthread.h:1.7.10.1 Mon Feb 2 22:01:34 2009 +++ src/sys/sys/kthread.h Sun Feb 20 07:04:15 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: kthread.h,v 1.7.10.1 2009/02/02 22:01:34 snj Exp $ */ +/* $NetBSD: kthread.h,v 1.7.10.1.8.1 2011/02/20 07:04:15 matt Exp $ */ /*- * Copyright (c) 1998, 2007, 2009 The NetBSD Foundation, Inc. @@ -44,6 +44,7 @@ #define KTHREAD_MPSAFE 0x02 /* does not need kernel_lock */ #define KTHREAD_INTR 0x04 /* interrupt handler */ #define KTHREAD_TS 0x08 /* timeshared */ +#define KTHREAD_JOINABLE 0x10 /* joinable thread */ int kthread_create(pri_t, int, struct cpu_info *, void (*)(void *), void *, @@ -51,6 +52,7 @@ __attribute__((__format__(__printf__,7,8))); void kthread_exit(int) __dead; void kthread_destroy(lwp_t *); +int kthread_join(lwp_t *); #endif /* _KERNEL */ #endif /* _SYS_KTHREAD_H_ */