Update some copyright notices to become more legal compliant.
[dragonfly.git] / sys / kern / kern_sysmsg.c
CommitLineData
1fa2b4b4 1/*
033a4603 2 * Copyright (c) 2003, 2004 Matthew Dillon <dillon@backplane.com>
1fa2b4b4
MD
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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.
13 *
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
24 * SUCH DAMAGE.
25 *
033a4603 26 * $DragonFly: src/sys/kern/Attic/kern_sysmsg.c,v 1.2 2004/06/28 02:57:11 drhodus Exp $
1fa2b4b4
MD
27 */
28
29/*
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.
35 *
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.
42 */
43
44#include <sys/param.h>
45#include <sys/systm.h>
46#include <sys/proc.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>
54#include <sys/uio.h>
55#include <sys/vmmeter.h>
56#include <sys/malloc.h>
57#ifdef KTRACE
58#include <sys/ktrace.h>
59#endif
60#include <sys/upcall.h>
61#include <sys/sysproto.h>
62#include <sys/sysunion.h>
63
64#include <vm/vm.h>
65#include <vm/vm_param.h>
66#include <sys/lock.h>
67#include <vm/pmap.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>
72
73#include <sys/msgport2.h>
74#include <sys/thread2.h>
75
76/*
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.
80 *
81 * NOTE: proc must be curproc.
82 */
83struct sysmsg *
84sysmsg_wait(struct proc *p, struct sysmsg *sysmsg, int nonblock)
85{
86 thread_t td = p->p_thread;
87
88 /*
89 * Get the next finished system call or the specified system call,
90 * blocking until it is finished (if requested).
91 */
92 if (sysmsg == NULL) {
93 if (TAILQ_FIRST(&p->p_sysmsgq) == NULL)
94 return(NULL);
95 if (nonblock) {
96 if ((sysmsg = lwkt_getport(&td->td_msgport)) == NULL)
97 return(NULL);
98 } else {
99 sysmsg = lwkt_waitport(&td->td_msgport, NULL);
100 }
101 } else {
102 if (nonblock && !lwkt_checkmsg(&sysmsg->lmsg))
103 return(NULL);
104 lwkt_waitport(&td->td_msgport, &sysmsg->lmsg);
105 }
106
107 /*
108 * sysmsg is not NULL here
109 */
110 TAILQ_REMOVE(&p->p_sysmsgq, sysmsg, msgq);
111 return(sysmsg);
112}
113
114/*
115 * Wait for all pending asynchronous system calls to complete, aborting them
116 * if requested (XXX).
117 */
118void
119sysmsg_rundown(struct proc *p, int doabort)
120{
121 struct sysmsg *sysmsg;
122 thread_t td = p->p_thread;
123 globaldata_t gd = td->td_gd;
124
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;
135 crit_exit_quick(td);
136 }
137}
138