2 * Copyright (c) 2003,2004 Matthew Dillon <dillon@backplane.com>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * $DragonFly: src/sys/kern/Attic/kern_sysmsg.c,v 1.1 2004/06/04 20:35:36 dillon Exp $
30 * SYSMSG is our system call message encapsulation and handling subsystem.
31 * System calls are now encapsulated in messages. A system call can execute
32 * synchronously or asynchronously. If a system call wishes to run
33 * asynchronously it returns EASYNC and the process records the pending system
34 * call message in p_sysmsgq.
36 * SYSMSGs work similarly to LWKT messages in that the originator can request
37 * a synchronous or asynchronous operation in isolation from the actual system
38 * call which can choose to run the system call synchronous or asynchronously
39 * (independant of what was requested). Like LWKT messages, the synchronous
40 * path avoids all queueing operations and is almost as fast as making a
41 * direct procedure call.
44 #include <sys/param.h>
45 #include <sys/systm.h>
47 #include <sys/pioctl.h>
48 #include <sys/kernel.h>
49 #include <sys/resourcevar.h>
50 #include <sys/signalvar.h>
51 #include <sys/syscall.h>
52 #include <sys/sysctl.h>
53 #include <sys/sysent.h>
55 #include <sys/vmmeter.h>
56 #include <sys/malloc.h>
58 #include <sys/ktrace.h>
60 #include <sys/upcall.h>
61 #include <sys/sysproto.h>
62 #include <sys/sysunion.h>
65 #include <vm/vm_param.h>
68 #include <vm/vm_kern.h>
69 #include <vm/vm_map.h>
70 #include <vm/vm_page.h>
71 #include <vm/vm_extern.h>
73 #include <sys/msgport2.h>
74 #include <sys/thread2.h>
77 * Wait for a system call message to be returned. If NULL is passed we
78 * wait for the next ready sysmsg and return it. We return NULL if there
79 * are no pending sysmsgs queued.
81 * NOTE: proc must be curproc.
84 sysmsg_wait(struct proc *p, struct sysmsg *sysmsg, int nonblock)
86 thread_t td = p->p_thread;
89 * Get the next finished system call or the specified system call,
90 * blocking until it is finished (if requested).
93 if (TAILQ_FIRST(&p->p_sysmsgq) == NULL)
96 if ((sysmsg = lwkt_getport(&td->td_msgport)) == NULL)
99 sysmsg = lwkt_waitport(&td->td_msgport, NULL);
102 if (nonblock && !lwkt_checkmsg(&sysmsg->lmsg))
104 lwkt_waitport(&td->td_msgport, &sysmsg->lmsg);
108 * sysmsg is not NULL here
110 TAILQ_REMOVE(&p->p_sysmsgq, sysmsg, msgq);
115 * Wait for all pending asynchronous system calls to complete, aborting them
116 * if requested (XXX).
119 sysmsg_rundown(struct proc *p, int doabort)
121 struct sysmsg *sysmsg;
122 thread_t td = p->p_thread;
123 globaldata_t gd = td->td_gd;
125 while (TAILQ_FIRST(&p->p_sysmsgq) != NULL) {
126 printf("WAITSYSMSG\n");
127 sysmsg = sysmsg_wait(p, NULL, 0);
128 printf("WAITSYSMSG %p\n", sysmsg);
129 KKASSERT(sysmsg != NULL);
130 /* XXX don't bother with pending copyouts */
131 /* XXX we really should do pending copyouts */
132 crit_enter_quick(td);
133 sysmsg->lmsg.opaque.ms_sysunnext = gd->gd_freesysun;
134 gd->gd_freesysun = (void *)sysmsg;