Add a helper for async syscalls
authorBarret Rhoden <brho@cs.berkeley.edu>
Wed, 28 Sep 2016 16:18:52 +0000 (12:18 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 6 Oct 2016 19:41:48 +0000 (15:41 -0400)
This helper makes an async syscall that will trigger the event queue upon
completion.  The caller doesn't check for completion manually - wait for
the ev_q.  This helps a few async syscall use cases, and avoids the need to
register the evq (CAS and whatnot) after submitting the syscall.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
user/parlib/include/parlib/parlib.h
user/parlib/syscall.c

index 10c8998..255c50f 100644 (file)
@@ -54,6 +54,8 @@ int         sys_abort_sysc_fd(int fd);
 int         sys_tap_fds(struct fd_tap_req *tap_reqs, size_t nr_reqs);
 
 void           syscall_async(struct syscall *sysc, unsigned long num, ...);
+void        syscall_async_evq(struct syscall *sysc, struct event_queue *evq,
+                              unsigned long num, ...);
 
 /* Control variables */
 extern bool parlib_wants_to_be_mcp;    /* instructs the 2LS to be an MCP */
index 92f14a7..2134dcf 100644 (file)
@@ -186,3 +186,24 @@ void syscall_async(struct syscall *sysc, unsigned long num, ...)
        va_end(args);
        __ros_arch_syscall((long)sysc, 1);
 }
+
+void syscall_async_evq(struct syscall *sysc, struct event_queue *evq,
+                       unsigned long num, ...)
+{
+       va_list args;
+
+       sysc->num = num;
+       atomic_set(&sysc->flags, SC_UEVENT);
+       sysc->ev_q = evq;
+       /* This is a little dangerous, since we'll usually pull more args than were
+        * passed in, ultimately reading gibberish off the stack. */
+       va_start(args, num);
+       sysc->arg0 = va_arg(args, long);
+       sysc->arg1 = va_arg(args, long);
+       sysc->arg2 = va_arg(args, long);
+       sysc->arg3 = va_arg(args, long);
+       sysc->arg4 = va_arg(args, long);
+       sysc->arg5 = va_arg(args, long);
+       va_end(args);
+       __ros_arch_syscall((long)sysc, 1);
+}