Annotation of sys/kern/kern_kthread.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: kern_kthread.c,v 1.27 2007/03/15 10:22:30 art Exp $ */
! 2: /* $NetBSD: kern_kthread.c,v 1.3 1998/12/22 21:21:36 kleink Exp $ */
! 3:
! 4: /*-
! 5: * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
! 6: * All rights reserved.
! 7: *
! 8: * This code is derived from software contributed to The NetBSD Foundation
! 9: * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
! 10: * NASA Ames Research Center.
! 11: *
! 12: * Redistribution and use in source and binary forms, with or without
! 13: * modification, are permitted provided that the following conditions
! 14: * are met:
! 15: * 1. Redistributions of source code must retain the above copyright
! 16: * notice, this list of conditions and the following disclaimer.
! 17: * 2. Redistributions in binary form must reproduce the above copyright
! 18: * notice, this list of conditions and the following disclaimer in the
! 19: * documentation and/or other materials provided with the distribution.
! 20: * 3. All advertising materials mentioning features or use of this software
! 21: * must display the following acknowledgement:
! 22: * This product includes software developed by the NetBSD
! 23: * Foundation, Inc. and its contributors.
! 24: * 4. Neither the name of The NetBSD Foundation nor the names of its
! 25: * contributors may be used to endorse or promote products derived
! 26: * from this software without specific prior written permission.
! 27: *
! 28: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
! 29: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! 30: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! 31: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
! 32: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! 33: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! 34: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! 35: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! 36: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! 37: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! 38: * POSSIBILITY OF SUCH DAMAGE.
! 39: */
! 40:
! 41: #include <sys/param.h>
! 42: #include <sys/systm.h>
! 43: #include <sys/kernel.h>
! 44: #include <sys/kthread.h>
! 45: #include <sys/proc.h>
! 46: #include <sys/wait.h>
! 47: #include <sys/malloc.h>
! 48: #include <sys/queue.h>
! 49:
! 50: #include <machine/cpu.h>
! 51:
! 52: /*
! 53: * note that stdarg.h and the ansi style va_start macro is used for both
! 54: * ansi and traditional c compilers.
! 55: * XXX: this requires that stdarg.h define: va_alist and va_dcl
! 56: */
! 57: #include <sys/stdarg.h>
! 58:
! 59: int kthread_create_now;
! 60:
! 61: /*
! 62: * Fork a kernel thread. Any process can request this to be done.
! 63: * The VM space and limits, etc. will be shared with proc0.
! 64: */
! 65: int
! 66: kthread_create(void (*func)(void *), void *arg,
! 67: struct proc **newpp, const char *fmt, ...)
! 68: {
! 69: struct proc *p2;
! 70: int error;
! 71: va_list ap;
! 72:
! 73: /*
! 74: * First, create the new process. Share the memory, file
! 75: * descriptors and don't leave the exit status around for the
! 76: * parent to wait for.
! 77: */
! 78: error = fork1(&proc0, 0, FORK_SHAREVM |FORK_NOZOMBIE |FORK_SIGHAND,
! 79: NULL, 0, func, arg, NULL, &p2);
! 80: if (error)
! 81: return (error);
! 82:
! 83: /*
! 84: * Mark it as a system process.
! 85: */
! 86: atomic_setbits_int(&p2->p_flag, P_SYSTEM);
! 87:
! 88: /* Name it as specified. */
! 89: va_start(ap, fmt);
! 90: vsnprintf(p2->p_comm, sizeof p2->p_comm, fmt, ap);
! 91: va_end(ap);
! 92:
! 93: /* All done! */
! 94: if (newpp != NULL)
! 95: *newpp = p2;
! 96: return (0);
! 97: }
! 98:
! 99: /*
! 100: * Cause a kernel thread to exit. Assumes the exiting thread is the
! 101: * current context.
! 102: */
! 103: void
! 104: kthread_exit(int ecode)
! 105: {
! 106:
! 107: /*
! 108: * XXX What do we do with the exit code? Should we even bother
! 109: * XXX with it? The parent (proc0) isn't going to do much with
! 110: * XXX it.
! 111: */
! 112: if (ecode != 0)
! 113: printf("WARNING: thread `%s' (%d) exits with status %d\n",
! 114: curproc->p_comm, curproc->p_pid, ecode);
! 115:
! 116: exit1(curproc, W_EXITCODE(ecode, 0), EXIT_NORMAL);
! 117:
! 118: /*
! 119: * XXX Fool the compiler. Making exit1() __dead is a can
! 120: * XXX of worms right now.
! 121: */
! 122: for (;;);
! 123: }
! 124:
! 125: struct kthread_q {
! 126: SIMPLEQ_ENTRY(kthread_q) kq_q;
! 127: void (*kq_func)(void *);
! 128: void *kq_arg;
! 129: };
! 130:
! 131: SIMPLEQ_HEAD(, kthread_q) kthread_q = SIMPLEQ_HEAD_INITIALIZER(kthread_q);
! 132:
! 133: /*
! 134: * Defer the creation of a kernel thread. Once the standard kernel threads
! 135: * and processes have been created, this queue will be run to callback to
! 136: * the caller to create threads for e.g. file systems and device drivers.
! 137: */
! 138: void
! 139: kthread_create_deferred(void (*func)(void *), void *arg)
! 140: {
! 141: struct kthread_q *kq;
! 142:
! 143: if (kthread_create_now) {
! 144: (*func)(arg);
! 145: return;
! 146: }
! 147:
! 148: kq = malloc(sizeof *kq, M_TEMP, M_NOWAIT);
! 149: if (kq == NULL)
! 150: panic("unable to allocate kthread_q");
! 151: bzero(kq, sizeof *kq);
! 152:
! 153: kq->kq_func = func;
! 154: kq->kq_arg = arg;
! 155:
! 156: SIMPLEQ_INSERT_TAIL(&kthread_q, kq, kq_q);
! 157: }
! 158:
! 159: void
! 160: kthread_run_deferred_queue(void)
! 161: {
! 162: struct kthread_q *kq;
! 163:
! 164: /* No longer need to defer kthread creation. */
! 165: kthread_create_now = 1;
! 166:
! 167: while ((kq = SIMPLEQ_FIRST(&kthread_q)) != NULL) {
! 168: SIMPLEQ_REMOVE_HEAD(&kthread_q, kq_q);
! 169: (*kq->kq_func)(kq->kq_arg);
! 170: free(kq, M_TEMP);
! 171: }
! 172: }
CVSweb