GCC/uthread callbacks on blocking syscalls (XCC)
[akaros.git] / kern / include / ros / syscall.h
index 7858d74..6423536 100644 (file)
@@ -8,6 +8,7 @@
 
 /* Flags for an individual syscall */
 #define SC_DONE                                        0x0001
+#define SC_PROGRESS                            0x0002
 
 struct syscall {
        unsigned int                            num;
@@ -26,6 +27,19 @@ struct syscall {
 
 #ifndef ROS_KERNEL
 
+/* Attempts to block on sysc, returning when it is done or progress has been
+ * made. */
+void ros_syscall_blockon(struct syscall *sysc);
+
+/* This weak version is meant to work if there is no 2LS.  For now we just
+ * spin, but in the future we could block the whole process. */
+static inline void __ros_syscall_blockon(struct syscall *sysc)
+{
+       while (!(sysc->flags & (SC_DONE | SC_PROGRESS)))
+               cpu_relax();
+}
+weak_alias(__ros_syscall_blockon, ros_syscall_blockon);
+
 /* TODO: make variants of __ros_syscall() based on the number of args (0 - 6) */
 /* These are simple synchronous system calls, built on top of the kernel's async
  * interface.  This version makes no assumptions about errno.  You usually don't
@@ -33,7 +47,7 @@ struct syscall {
 static inline long __ros_syscall(unsigned int _num, long _a0, long _a1, long _a2,
                                  long _a3, long _a4, long _a5, int *errno_loc)
 {
-       int num_started;
+       int num_started;        /* not used yet */
        struct syscall sysc = {0};
        sysc.num = _num;
        sysc.ev_q = 0;
@@ -44,8 +58,9 @@ static inline long __ros_syscall(unsigned int _num, long _a0, long _a1, long _a2
        sysc.arg4 = _a4;
        sysc.arg5 = _a5;
        num_started = __ros_arch_syscall(&sysc, 1);
+       /* Don't proceed til we are done */
        while (!(sysc.flags & SC_DONE))
-               cpu_relax();
+               ros_syscall_blockon(&sysc);
        if (errno_loc)
                *errno_loc = sysc.err;
        return sysc.retval;