async syscall work: The async syscall code got dated by recent LWKT
authorMatthew Dillon <dillon@dragonflybsd.org>
Fri, 4 Jun 2004 20:35:39 +0000 (20:35 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Fri, 4 Jun 2004 20:35:39 +0000 (20:35 +0000)
changes, set mp_abort_port and clear MSGF_DONE as appropriate.

If a system call returns EASYNC, record the message in p->p_sysmsgq so we
can run them down in exit1().

In exit1(), run down any asynch system calls that are still running.  Note
that this commit does not implement abort support (yet).

Get rid of lwkt_port->mp_refs, it was not being used and it is likely never
going to be used (reference counting LWKT is hazzardous anyway since it
doesn't really fit the access model).

Add lwkt_checkmsg() to support some of the rearranged async syscall code.

14 files changed:
sys/conf/files
sys/i386/i386/trap.c
sys/kern/init_main.c
sys/kern/kern_exit.c
sys/kern/kern_fork.c
sys/kern/kern_sysmsg.c [new file with mode: 0644]
sys/kern/kern_time.c
sys/kern/lwkt_msgport.c
sys/platform/pc32/i386/trap.c
sys/sys/msgport.h
sys/sys/msgport2.h
sys/sys/proc.h
sys/sys/sysent.h
sys/sys/sysmsg.h

index e2e6f3f..40151a6 100644 (file)
@@ -1,5 +1,5 @@
 # $FreeBSD: src/sys/conf/files,v 1.340.2.137 2003/06/04 17:10:30 sam Exp $
-# $DragonFly: src/sys/conf/files,v 1.61 2004/05/15 17:54:12 joerg Exp $
+# $DragonFly: src/sys/conf/files,v 1.62 2004/06/04 20:35:35 dillon Exp $
 #
 # The long compile-with and dependency lines are required because of
 # limitations in config: backslash-newline doesn't work in strings, and
@@ -644,6 +644,7 @@ kern/kern_systimer.c        standard
 kern/kern_mpipe.c      standard
 kern/kern_shutdown.c   standard
 kern/kern_sig.c                standard
+kern/kern_sysmsg.c     standard
 kern/kern_upcall.c     standard
 kern/kern_sfbuf.c      standard
 kern/kern_subr.c       standard
index 0fdc2e7..4ab7c91 100644 (file)
@@ -36,7 +36,7 @@
  *
  *     from: @(#)trap.c        7.4 (Berkeley) 5/13/91
  * $FreeBSD: src/sys/i386/i386/trap.c,v 1.147.2.11 2003/02/27 19:09:59 luoqi Exp $
- * $DragonFly: src/sys/i386/i386/Attic/trap.c,v 1.51 2004/05/05 19:26:38 dillon Exp $
+ * $DragonFly: src/sys/i386/i386/Attic/trap.c,v 1.52 2004/06/04 20:35:38 dillon Exp $
  */
 
 /*
@@ -1434,17 +1434,10 @@ sendsys2(struct trapframe frame)
                }
                switch(msgsize) {
                case 0:
-                       /*
-                        * Wait on port for message
-                        */
-                       sysun = lwkt_getport(&td->td_msgport);
-                       /* XXX block */
+                       sysun = (void *)sysmsg_wait(p, NULL, 0);
                        break;
                case -1:
-                       /*
-                        * Test port for message
-                        */
-                       sysun = lwkt_getport(&td->td_msgport);
+                       sysun = (void *)sysmsg_wait(p, NULL, 1);
                        break;
                default:
                        error = ENOSYS;
@@ -1456,7 +1449,6 @@ sendsys2(struct trapframe frame)
                        frame.tf_eax = (register_t)umsg;
                        if (sysun->sysmsg_copyout)
                                sysun->sysmsg_copyout(sysun);
-                       atomic_add_int_nonlocked(&td->td_msgport.mp_refs, -1);
                        sysun->nosys.usrmsg.umsg.u.ms_fds[0] = sysun->lmsg.u.ms_fds[0];
                        sysun->nosys.usrmsg.umsg.u.ms_fds[1] = sysun->lmsg.u.ms_fds[1];
                        sysun->nosys.usrmsg.umsg.ms_error = sysun->lmsg.ms_error;
@@ -1518,7 +1510,6 @@ sendsys2(struct trapframe frame)
                crit_exit_quick(td);
                sysun = malloc(sizeof(union sysunion), M_SYSMSG, M_WAITOK);
        }
-       atomic_add_int_nonlocked(&td->td_msgport.mp_refs, 1);
 
        /*
         * Copy the user request into the kernel copy of the user request.
@@ -1536,10 +1527,14 @@ sendsys2(struct trapframe frame)
        /*
         * Initialize the kernel message from the copied-in data and
         * pull in appropriate flags from the userland message.
+        *
+        * ms_abort_port is usually initialized in sendmsg/domsg, but since
+        * we are not calling those functions (yet), we have to do it manually.
         */
        lwkt_initmsg(&sysun->lmsg, &td->td_msgport, 0,
                        sysun->nosys.usrmsg.umsg.ms_cmd,
                        lwkt_cmd_op_none);
+       sysun->lmsg.ms_abort_port = sysun->lmsg.ms_reply_port;
        sysun->sysmsg_copyout = NULL;
        sysun->lmsg.opaque.ms_umsg = umsg;
        sysun->lmsg.ms_flags |= sysun->nosys.usrmsg.umsg.ms_flags & MSGF_ASYNC;
@@ -1588,8 +1583,14 @@ bad1:
         *
         * YYY Don't writeback message if execve() YYY
         */
-       if (error != EASYNC) {
-               atomic_add_int_nonlocked(&td->td_msgport.mp_refs, -1);
+       if (error == EASYNC) {
+               /*
+                * Since only the current process ever messes with msgq,
+                * we can safely manipulate it in parallel with the async
+                * operation.
+                */
+               TAILQ_INSERT_TAIL(&p->p_sysmsgq, &sysun->sysmsg, msgq);
+       } else {
                sysun->nosys.usrmsg.umsg.u.ms_fds[0] = sysun->lmsg.u.ms_fds[0];
                sysun->nosys.usrmsg.umsg.u.ms_fds[1] = sysun->lmsg.u.ms_fds[1];
                result = sysun->nosys.usrmsg.umsg.u.ms_fds[0]; /* for ktrace */
index 0381bf8..4111fd8 100644 (file)
@@ -40,7 +40,7 @@
  *
  *     @(#)init_main.c 8.9 (Berkeley) 1/21/94
  * $FreeBSD: src/sys/kern/init_main.c,v 1.134.2.8 2003/06/06 20:21:32 tegge Exp $
- * $DragonFly: src/sys/kern/init_main.c,v 1.32 2004/05/10 10:51:31 hmp Exp $
+ * $DragonFly: src/sys/kern/init_main.c,v 1.33 2004/06/04 20:35:36 dillon Exp $
  */
 
 #include "opt_init_path.h"
@@ -308,6 +308,7 @@ proc0_init(void *dummy __unused)
        session0.s_leader = p;
 
        p->p_sysent = &aout_sysvec;
+       TAILQ_INIT(&p->p_sysmsgq);
 
        p->p_flag = P_INMEM | P_SYSTEM | P_CP_RELEASED;
        p->p_stat = SRUN;
index 319a309..e27b067 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)kern_exit.c 8.7 (Berkeley) 2/12/94
  * $FreeBSD: src/sys/kern/kern_exit.c,v 1.92.2.11 2003/01/13 22:51:16 dillon Exp $
- * $DragonFly: src/sys/kern/kern_exit.c,v 1.34 2004/05/13 17:40:15 dillon Exp $
+ * $DragonFly: src/sys/kern/kern_exit.c,v 1.35 2004/06/04 20:35:36 dillon Exp $
  */
 
 #include "opt_compat.h"
@@ -124,8 +124,8 @@ exit1(int rv)
                panic("Going nowhere without my init!");
        }
 
+       sysmsg_rundown(p, 1);
        caps_exit(p->p_thread);
-
        aio_proc_rundown(p);
 
        /* are we a task leader? */
index e3d7881..3b4c141 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)kern_fork.c 8.6 (Berkeley) 4/8/94
  * $FreeBSD: src/sys/kern/kern_fork.c,v 1.72.2.14 2003/06/26 04:15:10 silby Exp $
- * $DragonFly: src/sys/kern/kern_fork.c,v 1.24 2004/04/24 04:32:03 drhodus Exp $
+ * $DragonFly: src/sys/kern/kern_fork.c,v 1.25 2004/06/04 20:35:36 dillon Exp $
  */
 
 #include "opt_ktrace.h"
@@ -278,6 +278,7 @@ fork1(struct proc *p1, int flags, struct proc **procp)
 
        newproc->p_wakeup = 0;
        newproc->p_vmspace = NULL;
+       TAILQ_INIT(&newproc->p_sysmsgq);
 
        /*
         * Find an unused process ID.  We remember a range of unused IDs
diff --git a/sys/kern/kern_sysmsg.c b/sys/kern/kern_sysmsg.c
new file mode 100644 (file)
index 0000000..0193f6f
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2003,2004 Matthew Dillon <dillon@backplane.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $DragonFly: src/sys/kern/Attic/kern_sysmsg.c,v 1.1 2004/06/04 20:35:36 dillon Exp $
+ */
+
+/*
+ * SYSMSG is our system call message encapsulation and handling subsystem.
+ * System calls are now encapsulated in messages.  A system call can execute
+ * synchronously or asynchronously.  If a system call wishes to run 
+ * asynchronously it returns EASYNC and the process records the pending system
+ * call message in p_sysmsgq.
+ *
+ * SYSMSGs work similarly to LWKT messages in that the originator can request
+ * a synchronous or asynchronous operation in isolation from the actual system
+ * call which can choose to run the system call synchronous or asynchronously
+ * (independant of what was requested).  Like LWKT messages, the synchronous
+ * path avoids all queueing operations and is almost as fast as making a 
+ * direct procedure call.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/pioctl.h>
+#include <sys/kernel.h>
+#include <sys/resourcevar.h>
+#include <sys/signalvar.h>
+#include <sys/syscall.h>
+#include <sys/sysctl.h>
+#include <sys/sysent.h>
+#include <sys/uio.h>
+#include <sys/vmmeter.h>
+#include <sys/malloc.h>
+#ifdef KTRACE
+#include <sys/ktrace.h>
+#endif
+#include <sys/upcall.h>
+#include <sys/sysproto.h>
+#include <sys/sysunion.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <sys/lock.h>
+#include <vm/pmap.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_map.h>
+#include <vm/vm_page.h>
+#include <vm/vm_extern.h>
+
+#include <sys/msgport2.h>
+#include <sys/thread2.h>
+
+/*
+ * Wait for a system call message to be returned.  If NULL is passed we
+ * wait for the next ready sysmsg and return it.  We return NULL if there
+ * are no pending sysmsgs queued.
+ *
+ * NOTE: proc must be curproc.
+ */
+struct sysmsg *
+sysmsg_wait(struct proc *p, struct sysmsg *sysmsg, int nonblock)
+{
+       thread_t td = p->p_thread;
+
+       /*
+        * Get the next finished system call or the specified system call,
+        * blocking until it is finished (if requested).
+        */
+       if (sysmsg == NULL) {
+               if (TAILQ_FIRST(&p->p_sysmsgq) == NULL)
+                       return(NULL);
+               if (nonblock) {
+                       if ((sysmsg = lwkt_getport(&td->td_msgport)) == NULL)
+                               return(NULL);
+               } else {
+                       sysmsg = lwkt_waitport(&td->td_msgport, NULL);
+               }
+       } else {
+               if (nonblock && !lwkt_checkmsg(&sysmsg->lmsg))
+                       return(NULL);
+               lwkt_waitport(&td->td_msgport, &sysmsg->lmsg);
+       }
+
+       /*
+        * sysmsg is not NULL here
+        */
+       TAILQ_REMOVE(&p->p_sysmsgq, sysmsg, msgq);
+       return(sysmsg);
+}
+
+/*
+ * Wait for all pending asynchronous system calls to complete, aborting them
+ * if requested (XXX).
+ */
+void
+sysmsg_rundown(struct proc *p, int doabort)
+{
+       struct sysmsg *sysmsg;
+       thread_t td = p->p_thread;
+       globaldata_t gd = td->td_gd;
+
+       while (TAILQ_FIRST(&p->p_sysmsgq) != NULL) {
+               printf("WAITSYSMSG\n");
+               sysmsg = sysmsg_wait(p, NULL, 0);
+               printf("WAITSYSMSG %p\n", sysmsg);
+               KKASSERT(sysmsg != NULL);
+               /* XXX don't bother with pending copyouts */
+               /* XXX we really should do pending copyouts */
+               crit_enter_quick(td);
+               sysmsg->lmsg.opaque.ms_sysunnext = gd->gd_freesysun;
+               gd->gd_freesysun = (void *)sysmsg;
+               crit_exit_quick(td);
+       }
+}
+
index 0ea0917..faddeec 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)kern_time.c 8.1 (Berkeley) 6/10/93
  * $FreeBSD: src/sys/kern/kern_time.c,v 1.68.2.1 2002/10/01 08:00:41 bde Exp $
- * $DragonFly: src/sys/kern/kern_time.c,v 1.15 2004/04/10 20:55:23 dillon Exp $
+ * $DragonFly: src/sys/kern/kern_time.c,v 1.16 2004/06/04 20:35:36 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -320,6 +320,7 @@ nanosleep(struct nanosleep_args *uap)
                                error = EINVAL;
                } else {
                        uap->sysmsg.copyout = nanosleep_copyout;
+                       uap->sysmsg.lmsg.ms_flags &= ~MSGF_DONE;
                        callout_init(&smsleep->timer);
                        callout_reset(&smsleep->timer, ticks, nanosleep_done, uap);
                        error = EASYNC;
@@ -348,8 +349,9 @@ static void
 nanosleep_done(void *arg)
 {
        struct nanosleep_args *uap = arg;
+       lwkt_msg_t msg = &uap->sysmsg.lmsg;
 
-       lwkt_replymsg(&uap->sysmsg.lmsg, 0);
+       lwkt_replymsg(msg, 0);
 }
 
 /*
index ecf5e52..1f08ef8 100644 (file)
@@ -26,7 +26,7 @@
  * NOTE! This file may be compiled for userland libraries as well as for
  * the kernel.
  *
- * $DragonFly: src/sys/kern/lwkt_msgport.c,v 1.21 2004/04/24 20:59:10 dillon Exp $
+ * $DragonFly: src/sys/kern/lwkt_msgport.c,v 1.22 2004/06/04 20:35:36 dillon Exp $
  */
 
 #ifdef _KERNEL
@@ -105,6 +105,10 @@ static void lwkt_putport_remote(lwkt_msg_t msg);
  *
  *     NOTE: you cannot safely request an abort until lwkt_sendmsg() returns
  *     to the caller.
+ *
+ *     NOTE: MSGF_DONE is left set.  The target port must clear it if the
+ *     message is to be handled asynchronously, while the synchronous case
+ *     can just ignore it.
  */
 void
 lwkt_sendmsg(lwkt_port_t port, lwkt_msg_t msg)
@@ -140,6 +144,10 @@ lwkt_sendmsg(lwkt_port_t port, lwkt_msg_t msg)
  *
  *     NOTE: you cannot safely request an abort until lwkt_domsg() blocks.
  *     XXX this probably needs some work.
+ *
+ *     NOTE: MSGF_DONE is left set.  The target port must clear it if the
+ *     message is to be handled asynchronously, while the synchronous case
+ *     can just ignore it.
  */
 int
 lwkt_domsg(lwkt_port_t port, lwkt_msg_t msg)
@@ -346,6 +354,12 @@ lwkt_default_replyport(lwkt_port_t port, lwkt_msg_t msg)
  *     MSGF_QUEUED prior to sending any IPIs in order to interlock against
  *     ABORT requests and other tests that might be performed.
  *
+ *     Note that messages start out as synchronous entities, and as an
+ *     optimization MSGF_DONE is usually left set (so in the synchronous path
+ *     no modifications to ms_flags are ever required).  If a message becomes
+ *     async, i.e. you return EASYNC, then MSGF_DONE must be cleared or
+ *     lwkt_replymsg() will wind up being a NOP.
+ *
  *     The inline must be called from a critical section (the remote function
  *     is called from an IPI and will be in a critical section).
  */
index 4b24413..b725832 100644 (file)
@@ -36,7 +36,7 @@
  *
  *     from: @(#)trap.c        7.4 (Berkeley) 5/13/91
  * $FreeBSD: src/sys/i386/i386/trap.c,v 1.147.2.11 2003/02/27 19:09:59 luoqi Exp $
- * $DragonFly: src/sys/platform/pc32/i386/trap.c,v 1.51 2004/05/05 19:26:38 dillon Exp $
+ * $DragonFly: src/sys/platform/pc32/i386/trap.c,v 1.52 2004/06/04 20:35:38 dillon Exp $
  */
 
 /*
@@ -1434,17 +1434,10 @@ sendsys2(struct trapframe frame)
                }
                switch(msgsize) {
                case 0:
-                       /*
-                        * Wait on port for message
-                        */
-                       sysun = lwkt_getport(&td->td_msgport);
-                       /* XXX block */
+                       sysun = (void *)sysmsg_wait(p, NULL, 0);
                        break;
                case -1:
-                       /*
-                        * Test port for message
-                        */
-                       sysun = lwkt_getport(&td->td_msgport);
+                       sysun = (void *)sysmsg_wait(p, NULL, 1);
                        break;
                default:
                        error = ENOSYS;
@@ -1456,7 +1449,6 @@ sendsys2(struct trapframe frame)
                        frame.tf_eax = (register_t)umsg;
                        if (sysun->sysmsg_copyout)
                                sysun->sysmsg_copyout(sysun);
-                       atomic_add_int_nonlocked(&td->td_msgport.mp_refs, -1);
                        sysun->nosys.usrmsg.umsg.u.ms_fds[0] = sysun->lmsg.u.ms_fds[0];
                        sysun->nosys.usrmsg.umsg.u.ms_fds[1] = sysun->lmsg.u.ms_fds[1];
                        sysun->nosys.usrmsg.umsg.ms_error = sysun->lmsg.ms_error;
@@ -1518,7 +1510,6 @@ sendsys2(struct trapframe frame)
                crit_exit_quick(td);
                sysun = malloc(sizeof(union sysunion), M_SYSMSG, M_WAITOK);
        }
-       atomic_add_int_nonlocked(&td->td_msgport.mp_refs, 1);
 
        /*
         * Copy the user request into the kernel copy of the user request.
@@ -1536,10 +1527,14 @@ sendsys2(struct trapframe frame)
        /*
         * Initialize the kernel message from the copied-in data and
         * pull in appropriate flags from the userland message.
+        *
+        * ms_abort_port is usually initialized in sendmsg/domsg, but since
+        * we are not calling those functions (yet), we have to do it manually.
         */
        lwkt_initmsg(&sysun->lmsg, &td->td_msgport, 0,
                        sysun->nosys.usrmsg.umsg.ms_cmd,
                        lwkt_cmd_op_none);
+       sysun->lmsg.ms_abort_port = sysun->lmsg.ms_reply_port;
        sysun->sysmsg_copyout = NULL;
        sysun->lmsg.opaque.ms_umsg = umsg;
        sysun->lmsg.ms_flags |= sysun->nosys.usrmsg.umsg.ms_flags & MSGF_ASYNC;
@@ -1588,8 +1583,14 @@ bad1:
         *
         * YYY Don't writeback message if execve() YYY
         */
-       if (error != EASYNC) {
-               atomic_add_int_nonlocked(&td->td_msgport.mp_refs, -1);
+       if (error == EASYNC) {
+               /*
+                * Since only the current process ever messes with msgq,
+                * we can safely manipulate it in parallel with the async
+                * operation.
+                */
+               TAILQ_INSERT_TAIL(&p->p_sysmsgq, &sysun->sysmsg, msgq);
+       } else {
                sysun->nosys.usrmsg.umsg.u.ms_fds[0] = sysun->lmsg.u.ms_fds[0];
                sysun->nosys.usrmsg.umsg.u.ms_fds[1] = sysun->lmsg.u.ms_fds[1];
                result = sysun->nosys.usrmsg.umsg.u.ms_fds[0]; /* for ktrace */
index e5b386b..6a06379 100644 (file)
@@ -3,7 +3,7 @@
  *
  *     Implements LWKT messages and ports.
  * 
- * $DragonFly: src/sys/sys/msgport.h,v 1.17 2004/04/20 01:52:24 dillon Exp $
+ * $DragonFly: src/sys/sys/msgport.h,v 1.18 2004/06/04 20:35:39 dillon Exp $
  */
 
 #ifndef _SYS_MSGPORT_H_
@@ -122,7 +122,7 @@ MALLOC_DECLARE(M_LWKTMSG);
 typedef struct lwkt_port {
     lwkt_msg_queue     mp_msgq;
     int                        mp_flags;
-    int                        mp_refs;        /* references to port structure */
+    int                        mp_unused01;
     struct thread      *mp_td;
     int                        (*mp_putport)(lwkt_port_t, lwkt_msg_t);
     void *             (*mp_waitport)(lwkt_port_t, lwkt_msg_t);
index 7ea26bb..216ebeb 100644 (file)
@@ -3,7 +3,7 @@
  *
  *     Implements Inlines for LWKT messages and ports.
  * 
- * $DragonFly: src/sys/sys/msgport2.h,v 1.9 2004/04/20 01:52:24 dillon Exp $
+ * $DragonFly: src/sys/sys/msgport2.h,v 1.10 2004/06/04 20:35:39 dillon Exp $
  */
 
 #ifndef _SYS_MSGPORT2_H_
@@ -22,6 +22,9 @@ typedef int (*lwkt_cmd_func_t)(lwkt_msg_t);
  * an abort MSGF_ABORTABLE must be passed in flags and an abort command
  * supplied.  If abort is not supported then lwkt_cmd_op_none is passed as
  * the abort command argument by convention.
+ *
+ * Note that other areas of the LWKT msg may already be initialized, so we
+ * do not zero the message here.
  */
 static __inline
 void
@@ -109,5 +112,12 @@ lwkt_waitport(lwkt_port_t port, lwkt_msg_t msg)
     return(port->mp_waitport(port, msg));
 }
 
+static __inline
+int
+lwkt_checkmsg(lwkt_msg_t msg)
+{
+    return(msg->ms_flags & MSGF_DONE);
+}
+
 #endif
 
index 7dac292..732aa6b 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)proc.h      8.15 (Berkeley) 5/19/95
  * $FreeBSD: src/sys/sys/proc.h,v 1.99.2.9 2003/06/06 20:21:32 tegge Exp $
- * $DragonFly: src/sys/sys/proc.h,v 1.49 2004/05/03 16:06:26 joerg Exp $
+ * $DragonFly: src/sys/sys/proc.h,v 1.50 2004/06/04 20:35:39 dillon Exp $
  */
 
 #ifndef _SYS_PROC_H_
@@ -236,6 +236,7 @@ struct      proc {
        struct upcall *p_upcall; /* USERLAND POINTER! registered upcall */
        struct sched *p_sched;  /* work-in-progress / Peter Kadau */
        int     p_numposixlocks; /* number of POSIX locks */
+       TAILQ_HEAD(, sysmsg) p_sysmsgq; /* Recorded asynch system calls */
 };
 
 #if defined(_KERNEL)
index a806b32..dfe0561 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/sys/sysent.h,v 1.27.2.5 2002/03/17 11:08:38 alfred Exp $
- * $DragonFly: src/sys/sys/sysent.h,v 1.6 2003/11/20 06:05:31 dillon Exp $
+ * $DragonFly: src/sys/sys/sysent.h,v 1.7 2004/06/04 20:35:39 dillon Exp $
  */
 
 #ifndef _SYS_SYSENT_H_
@@ -43,7 +43,8 @@ typedef       int     sy_call_t (void *);
 
 struct sysent {                /* system call table */
        int     sy_narg;        /* number of arguments */
-       sy_call_t *sy_call;     /* implementing function */
+       sy_call_t *sy_call;     /* start function */
+       sy_call_t *sy_abort;    /* abort function (only if start was async) */
 };
 
 #define SYF_ARGMASK    0x0000FFFF
index fcc9eed..e23bbb4 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * SYS/SYSMSG.H
  *
- * $DragonFly: src/sys/sys/sysmsg.h,v 1.4 2003/11/20 06:05:31 dillon Exp $
+ * $DragonFly: src/sys/sys/sysmsg.h,v 1.5 2004/06/04 20:35:39 dillon Exp $
  */
 
 #ifndef _SYS_SYSMSG_H_
 /*
  * The sysmsg holds the kernelland version of a system call.
  * It typically preceeds the usrmsg and syscall arguments in sysunion
- * (see sys/sysunion.h)
+ * (see sys/sysunion.h).  Note that msgq field is used by the governing
+ * process to record a system call that returns EASYNC in order to be able
+ * to properly abort and/or wait on it in exit1().  This is different from
+ * any localized queueing of the LWKT message that the syscall itself might
+ * do.
  */
 union sysunion;
 
 struct sysmsg {
        struct lwkt_msg lmsg;
        void            (*copyout)(union sysunion *sysun);
+       TAILQ_ENTRY(sysmsg)     msgq;
        union {
            struct sysmsg_sleep {
                struct lwkt_msg lmsg;
@@ -36,6 +41,11 @@ struct sysmsg {
        } sm;
 };
 
+struct proc;
+
+struct sysmsg *sysmsg_wait(struct proc *p, struct sysmsg *sysmsg, int nonblock);
+void sysmsg_rundown(struct proc *p, int doabort);
+
 #endif
 
 /*