2 * Copyright (c) 2003,2004 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * $DragonFly: src/sys/kern/Attic/kern_sysmsg.c,v 1.4 2004/08/12 19:59:30 eirikn Exp $
38 * SYSMSG is our system call message encapsulation and handling subsystem.
39 * System calls are now encapsulated in messages. A system call can execute
40 * synchronously or asynchronously. If a system call wishes to run
41 * asynchronously it returns EASYNC and the process records the pending system
42 * call message in p_sysmsgq.
44 * SYSMSGs work similarly to LWKT messages in that the originator can request
45 * a synchronous or asynchronous operation in isolation from the actual system
46 * call which can choose to run the system call synchronous or asynchronously
47 * (independant of what was requested). Like LWKT messages, the synchronous
48 * path avoids all queueing operations and is almost as fast as making a
49 * direct procedure call.
52 #include <sys/param.h>
53 #include <sys/systm.h>
55 #include <sys/pioctl.h>
56 #include <sys/kernel.h>
57 #include <sys/resourcevar.h>
58 #include <sys/signalvar.h>
59 #include <sys/syscall.h>
60 #include <sys/sysctl.h>
61 #include <sys/sysent.h>
63 #include <sys/vmmeter.h>
64 #include <sys/malloc.h>
66 #include <sys/ktrace.h>
68 #include <sys/upcall.h>
69 #include <sys/sysproto.h>
70 #include <sys/sysunion.h>
73 #include <vm/vm_param.h>
76 #include <vm/vm_kern.h>
77 #include <vm/vm_map.h>
78 #include <vm/vm_page.h>
79 #include <vm/vm_extern.h>
81 #include <sys/msgport2.h>
82 #include <sys/thread2.h>
85 * Sysctl to limit max in progress syscall messages per process. 0 for
89 SYSCTL_INT(_kern, OID_AUTO, max_sysmsg, CTLFLAG_RW, &max_sysmsg, 0,
90 "Max sysmsg's a process can have running");
93 * Wait for a system call message to be returned. If NULL is passed we
94 * wait for the next ready sysmsg and return it. We return NULL if there
95 * are no pending sysmsgs queued.
97 * NOTE: proc must be curproc.
100 sysmsg_wait(struct proc *p, struct sysmsg *sysmsg, int nonblock)
102 thread_t td = p->p_thread;
105 * Get the next finished system call or the specified system call,
106 * blocking until it is finished (if requested).
108 if (sysmsg == NULL) {
109 if (TAILQ_FIRST(&p->p_sysmsgq) == NULL)
112 if ((sysmsg = lwkt_getport(&td->td_msgport)) == NULL)
115 sysmsg = lwkt_waitport(&td->td_msgport, NULL);
118 if (nonblock && !lwkt_checkmsg(&sysmsg->lmsg))
120 lwkt_waitport(&td->td_msgport, &sysmsg->lmsg);
124 * sysmsg is not NULL here
126 TAILQ_REMOVE(&p->p_sysmsgq, sysmsg, msgq);
132 * Wait for all pending asynchronous system calls to complete, aborting them
133 * if requested (XXX).
136 sysmsg_rundown(struct proc *p, int doabort)
138 struct sysmsg *sysmsg;
139 thread_t td = p->p_thread;
140 globaldata_t gd = td->td_gd;
142 while (TAILQ_FIRST(&p->p_sysmsgq) != NULL) {
143 printf("WAITSYSMSG\n");
144 sysmsg = sysmsg_wait(p, NULL, 0);
145 printf("WAITSYSMSG %p\n", sysmsg);
146 KKASSERT(sysmsg != NULL);
147 /* XXX don't bother with pending copyouts */
148 /* XXX we really should do pending copyouts */
149 crit_enter_quick(td);
150 sysmsg->lmsg.opaque.ms_sysunnext = gd->gd_freesysun;
151 gd->gd_freesysun = (void *)sysmsg;