parlib: Add the uthread_is_thread0() helper
[akaros.git] / user / parlib / syscall.c
index 92f14a7..aaf3a1c 100644 (file)
@@ -3,6 +3,8 @@
 #include <parlib/parlib.h>
 #include <parlib/vcore.h>
 #include <parlib/serialize.h>
+#include <parlib/assert.h>
+#include <parlib/stdio.h>
 
 int sys_proc_destroy(int pid, int exitcode)
 {
@@ -39,7 +41,7 @@ void sys_reboot(void)
 
 void sys_yield(bool being_nice)
 {
-       ros_syscall(SYS_yield, being_nice, 0, 0, 0, 0, 0);
+       ros_syscall(SYS_proc_yield, being_nice, 0, 0, 0, 0, 0);
 }
 
 int sys_proc_create(const char *path, size_t path_l, char *const argv[],
@@ -83,7 +85,13 @@ int sys_self_notify(uint32_t vcoreid, unsigned int ev_type,
        return ros_syscall(SYS_self_notify, vcoreid, ev_type, u_msg, priv, 0, 0);
 }
 
-int sys_halt_core(unsigned int usec)
+int sys_send_event(struct event_queue *ev_q, struct event_msg *ev_msg,
+                   uint32_t vcoreid)
+{
+       return ros_syscall(SYS_send_event, ev_q, ev_msg, vcoreid, 0, 0, 0);
+}
+
+int sys_halt_core(unsigned long usec)
 {
        return ros_syscall(SYS_halt_core, usec, 0, 0, 0, 0, 0);
 }
@@ -93,7 +101,7 @@ void* sys_init_arsc()
        return (void*)ros_syscall(SYS_init_arsc, 0, 0, 0, 0, 0, 0);
 }
 
-int sys_block(unsigned int usec)
+int sys_block(unsigned long usec)
 {
        return ros_syscall(SYS_block, usec, 0, 0, 0, 0, 0);
 }
@@ -120,6 +128,9 @@ int sys_change_vcore(uint32_t vcoreid, bool enable_my_notif)
         * unlocking the proc, before finish_sysc()), and the act of finishing would
         * write onto our stack.  Thus we use the per-vcore struct. */
        int flags;
+
+       /* Sanity check.  Uthreads can call this, but only when notifs disabled. */
+       assert(!notif_is_enabled(vcore_id()));
        /* Need to wait while a previous syscall is not done or locked.  Since this
         * should only be called from VC ctx, we'll just spin.  Should be extremely
         * rare.  Note flags is initialized to SC_DONE. */
@@ -186,3 +197,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);
+}