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@.
This commit is contained in:
parent
1616addc6a
commit
6af3749398
@ -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 @@ __KERNEL_RCSID(0, "$NetBSD: kern_kthread.c,v 1.27 2009/10/21 21:12:06 rmind Exp
|
||||
|
||||
/*
|
||||
* 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 @@ kthread_create(pri_t pri, int flag, struct cpu_info *ci,
|
||||
{
|
||||
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 @@ kthread_create(pri_t pri, int flag, struct cpu_info *ci,
|
||||
} 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 @@ kthread_create(pri_t pri, int flag, struct cpu_info *ci,
|
||||
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 @@ kthread_create(pri_t pri, int flag, struct cpu_info *ci,
|
||||
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 @@ kthread_exit(int ecode)
|
||||
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;
|
||||
}
|
||||
|
@ -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 @@ int kthread_create(pri_t, int, struct cpu_info *,
|
||||
__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_ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user