Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Re-implement kthread_join(9), so that it actually works (hi ...
details: https://anonhg.NetBSD.org/src/rev/d04350a45c00
branches: trunk
changeset: 765087:d04350a45c00
user: rmind <rmind%NetBSD.org@localhost>
date: Thu May 19 03:07:29 2011 +0000
description:
Re-implement kthread_join(9), so that it actually works (hi haad@).
diffstat:
share/man/man9/kthread.9 | 34 ++++++-----
sys/kern/init_main.c | 5 +-
sys/kern/kern_kthread.c | 127 ++++++++++++++++++++++------------------------
sys/sys/kthread.h | 20 ++++--
sys/sys/lwp.h | 3 +-
5 files changed, 97 insertions(+), 92 deletions(-)
diffs (truncated from 389 to 300 lines):
diff -r 5fe86bbe8ba5 -r d04350a45c00 share/man/man9/kthread.9
--- a/share/man/man9/kthread.9 Thu May 19 02:56:03 2011 +0000
+++ b/share/man/man9/kthread.9 Thu May 19 03:07:29 2011 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: kthread.9,v 1.24 2010/12/02 12:54:13 wiz Exp $
+.\" $NetBSD: kthread.9,v 1.25 2011/05/19 03:07:30 rmind Exp $
.\"
.\" Copyright (c) 2000, 2007, 2008 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -27,7 +27,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd May 13, 2010
+.Dd May 19, 2011
.Dt KTHREAD 9
.Os
.Sh NAME
@@ -89,16 +89,13 @@
.Dv NULL
if not required.
.It Fa newlp
-A pointer to receive the new lwp structure for the kernel thread.
-May not be
-.Dv NULL
-if
+A pointer to receive the new LWP structure for the kernel thread.
+May be
+.Dv NULL ,
+unless
.Dv KTHREAD_JOINABLE
is specified in
-.Fa flags ;
-otherwise may be
-.Dv NULL
-if not required.
+.Fa flags .
.It Fa fmt
A string containing format information used to display the kernel
thread name.
@@ -129,7 +126,7 @@
Causes the kthread to be created in the
.Dv SCHED_OTHER
class (timeshared).
-The threads' priority will be dynamically adjusted by the scheduler.
+The priority of thread will be dynamically adjusted by the scheduler.
Increased activity by the kthread will cause its priority to fall;
decreased activity will cause its priority to rise.
By default, kthreads are created in the
@@ -143,10 +140,11 @@
adjusted by the scheduler.
.It Dv KTHREAD_JOINABLE
Requests creation of joinable kthread.
-When this flag is specified, the
+In such case
+.Fn kthread_exit
+will wait until
.Fn kthread_join
-function can be called only once for the lwp structure returned in
-.Fa newlp .
+will be called.
.El
.It Fn kthread_destroy "l"
From another thread executing in the kernel, cause a kthread to exit.
@@ -157,9 +155,13 @@
Exit from a kernel thread.
Must only be called by a kernel thread.
.It Fn kthread_join "l"
-Suspend execution of the LWP until the target kthread terminates.
+Suspend execution of calling thread until the target kthread terminates.
Conceptually the function can be compared to the user space
-.Xr pthread_join 3 .
+.Xr pthread_join 3 ,
+however it must be called only once for kernel thread which was created using
+.Dv KTHREAD_JOIN
+flag and would wait on
+.Fa kthread_exit .
.El
.Sh RETURN VALUES
Upon successful completion,
diff -r 5fe86bbe8ba5 -r d04350a45c00 sys/kern/init_main.c
--- a/sys/kern/init_main.c Thu May 19 02:56:03 2011 +0000
+++ b/sys/kern/init_main.c Thu May 19 03:07:29 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: init_main.c,v 1.428 2011/04/14 16:20:52 yamt Exp $ */
+/* $NetBSD: init_main.c,v 1.429 2011/05/19 03:07:29 rmind Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -97,7 +97,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.428 2011/04/14 16:20:52 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.429 2011/05/19 03:07:29 rmind Exp $");
#include "opt_ddb.h"
#include "opt_ipsec.h"
@@ -304,6 +304,7 @@
once_init();
mutex_init(&cpu_lock, MUTEX_DEFAULT, IPL_NONE);
kernconfig_lock_init();
+ kthread_sysinit();
/* Initialize the device switch tables. */
devsw_init();
diff -r 5fe86bbe8ba5 -r d04350a45c00 sys/kern/kern_kthread.c
--- a/sys/kern/kern_kthread.c Thu May 19 02:56:03 2011 +0000
+++ b/sys/kern/kern_kthread.c Thu May 19 03:07:29 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_kthread.c,v 1.32 2011/04/26 17:40:38 ahoka Exp $ */
+/* $NetBSD: kern_kthread.c,v 1.33 2011/05/19 03:07:29 rmind Exp $ */
/*-
* Copyright (c) 1998, 1999, 2007, 2009 The NetBSD Foundation, Inc.
@@ -31,45 +31,45 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_kthread.c,v 1.32 2011/04/26 17:40:38 ahoka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_kthread.c,v 1.33 2011/05/19 03:07:29 rmind Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/kthread.h>
-#include <sys/proc.h>
+#include <sys/mutex.h>
#include <sys/sched.h>
#include <sys/kmem.h>
#include <uvm/uvm_extern.h>
-
-/*
- * note that stdarg.h and the ansi style va_start macro is used for both
- * ansi and traditional c complers.
- * XXX: this requires that stdarg.h define: va_alist and va_dcl
- */
#include <machine/stdarg.h>
+static lwp_t * kthread_jtarget;
+static kmutex_t kthread_lock;
+static kcondvar_t kthread_cv;
+
+void
+kthread_sysinit(void)
+{
+
+ mutex_init(&kthread_lock, MUTEX_DEFAULT, IPL_NONE);
+ cv_init(&kthread_cv, "kthrwait");
+ kthread_jtarget = NULL;
+}
+
/*
- * 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 *.
+ * kthread_create: create a kernel thread, that is, system-only LWP.
*/
int
kthread_create(pri_t pri, int flag, struct cpu_info *ci,
- void (*func)(void *), void *arg,
- lwp_t **lp, const char *fmt, ...)
+ void (*func)(void *), void *arg, lwp_t **lp, const char *fmt, ...)
{
lwp_t *l;
vaddr_t uaddr;
- int error, lc, lwp_flags;
+ int error, lc;
va_list ap;
- lwp_flags = LWP_DETACHED;
+ KASSERT((flag & KTHREAD_INTR) == 0 || (flag & KTHREAD_MPSAFE) != 0);
uaddr = uvm_uarea_system_alloc();
if (uaddr == 0) {
@@ -81,11 +81,7 @@
lc = SCHED_RR;
}
- if ((flag & KTHREAD_JOINABLE) != 0) {
- lwp_flags &= ~LWP_DETACHED;
- }
-
- error = lwp_create(&lwp0, &proc0, uaddr, lwp_flags, NULL,
+ error = lwp_create(&lwp0, &proc0, uaddr, LWP_DETACHED, NULL,
0, func, arg, &l, lc);
if (error) {
uvm_uarea_system_free(uaddr);
@@ -105,15 +101,6 @@
/*
* Set parameters.
*/
- if ((flag & KTHREAD_INTR) != 0) {
- 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. */
@@ -134,10 +121,17 @@
l->l_pflag |= LP_BOUND;
l->l_cpu = ci;
}
- if ((flag & KTHREAD_INTR) != 0)
+
+ if ((flag & KTHREAD_JOINABLE) != 0) {
+ KASSERT(lp != NULL);
+ l->l_pflag |= LP_JOINABLE;
+ }
+ if ((flag & KTHREAD_INTR) != 0) {
l->l_pflag |= LP_INTR;
- if ((flag & KTHREAD_MPSAFE) == 0)
+ }
+ if ((flag & KTHREAD_MPSAFE) == 0) {
l->l_pflag &= ~LP_MPSAFE;
+ }
/*
* Set the new LWP running, unless the caller has requested
@@ -152,10 +146,10 @@
mutex_exit(proc0.p_lock);
/* All done! */
- if (lp != NULL)
+ if (lp != NULL) {
*lp = l;
-
- return (0);
+ }
+ return 0;
}
/*
@@ -176,15 +170,20 @@
name, l->l_lid, ecode);
}
+ /* Barrier for joining. */
+ if (l->l_pflag & LP_JOINABLE) {
+ mutex_enter(&kthread_lock);
+ while (kthread_jtarget != l) {
+ cv_wait(&kthread_cv, &kthread_lock);
+ }
+ kthread_jtarget = NULL;
+ cv_broadcast(&kthread_cv);
+ mutex_exit(&kthread_lock);
+ }
+
/* And exit.. */
lwp_exit(l);
-
- /*
- * XXX Fool the compiler. Making exit1() __noreturn__ is a can
- * XXX of worms right now.
- */
- for (;;)
- ;
+ KASSERT(false);
}
/*
@@ -193,18 +192,10 @@
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);
}
@@ -214,18 +205,24 @@
int
kthread_join(lwp_t *l)
{
- lwpid_t departed;
- proc_t *p;
- int error;
KASSERT((l->l_flag & LW_SYSTEM) != 0);
Home |
Main Index |
Thread Index |
Old Index