Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Add support for kthread_join in our kernel thread implem...



details:   https://anonhg.NetBSD.org/src/rev/0d56ee4f2fac
branches:  trunk
changeset: 754766:0d56ee4f2fac
user:      haad <haad%NetBSD.org@localhost>
date:      Tue May 11 22:26:00 2010 +0000

description:
Add support for kthread_join in our kernel thread implementation. This is used
by zfs but I think that it can be generaly usefull. Thread need to be created
with KTHREAD_JOINABLE flag and can be joined only once.
When joinable thread was created it will not e automatically reaped from system
and kthread_join must be called on it to reap it.

Ok by ad@.

diffstat:

 sys/kern/kern_kthread.c |  61 +++++++++++++++++++++++++++++++++++++++++++-----
 sys/sys/kthread.h       |   4 ++-
 2 files changed, 57 insertions(+), 8 deletions(-)

diffs (146 lines):

diff -r a5643acac2ba -r 0d56ee4f2fac sys/kern/kern_kthread.c
--- a/sys/kern/kern_kthread.c   Tue May 11 22:21:05 2010 +0000
+++ b/sys/kern/kern_kthread.c   Tue May 11 22:26:00 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_kthread.c,v 1.27 2009/10/21 21:12:06 rmind Exp $  */
+/*     $NetBSD: kern_kthread.c,v 1.28 2010/05/11 22:26:00 haad 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.27 2009/10/21 21:12:06 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_kthread.c,v 1.28 2010/05/11 22:26:00 haad 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,
@@ -60,10 +66,11 @@
 {
        lwp_t *l;
        vaddr_t uaddr;
-       int error;
+       int error, lc, lwp_flags;
        va_list ap;
-       int lc;
 
+       lwp_flags = LWP_DETACHED;
+       
        uaddr = uvm_uarea_alloc();
        if (uaddr == 0) {
                return ENOMEM;
@@ -73,7 +80,12 @@
        } else {
                lc = SCHED_RR;
        }
-       error = lwp_create(&lwp0, &proc0, uaddr, LWP_DETACHED, NULL,
+
+       if ((flag & KTHREAD_JOINABLE) != 0) {
+               lwp_flags &= ~LWP_DETACHED;
+       }
+
+       error = lwp_create(&lwp0, &proc0, uaddr, lwp_flags, NULL,
            0, func, arg, &l, lc);
        if (error) {
                uvm_uarea_free(uaddr);
@@ -82,7 +94,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);
@@ -97,6 +109,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. */
@@ -182,9 +199,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;
+}
diff -r a5643acac2ba -r 0d56ee4f2fac sys/sys/kthread.h
--- a/sys/sys/kthread.h Tue May 11 22:21:05 2010 +0000
+++ b/sys/sys/kthread.h Tue May 11 22:26:00 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kthread.h,v 1.8 2009/01/29 22:00:26 ad Exp $   */
+/*     $NetBSD: kthread.h,v 1.9 2010/05/11 22:26:00 haad 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_ */



Home | Main Index | Thread Index | Old Index