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