[BACK]Return to kern_kthread.c CVS log [TXT][DIR] Up to [local] / sys / kern

Annotation of sys/kern/kern_kthread.c, Revision 1.1.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