Expose akaros_syscall_sync through libc (XCC)
authorKevin Klues <klueska@cs.berkeley.edu>
Sun, 28 Jul 2013 23:59:38 +0000 (16:59 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Mon, 29 Jul 2013 01:47:22 +0000 (18:47 -0700)
This function takes a syscall struct as a parameter and performs a
single synchyronous syscall using that struct.  If the syscall is not
complete upon exiting the kernel the currently running thread will be
handed off to the 2LS and blocked there.

tools/compilers/gcc-glibc/glibc-2.14.1-ros/sysdeps/ros/Versions
tools/compilers/gcc-glibc/glibc-2.14.1-ros/sysdeps/ros/sys/syscall.h
tools/compilers/gcc-glibc/glibc-2.14.1-ros/sysdeps/ros/syscall.c

index c848333..1ae2ca8 100644 (file)
@@ -2,6 +2,7 @@ libc {
   GLIBC_2.0 {
     __errno_location;
     ros_syscall_blockon;
+    ros_syscall_sync;
     __ros_scp_syscall_blockon;
     __ros_scp_simple_evq;
     __ros_syscall;
index 64ff570..3c8f648 100644 (file)
@@ -22,6 +22,9 @@ extern "C" {
    __ros_syscall_errno(which, (long)(a0), (long)(a1), (long)(a2), (long)(a3), \
                        (long)(a4), (long)(a5))
 
+/* Issue a single syscall and block into the 2LS until it completes */
+void ros_syscall_sync(struct syscall *sysc);
+
 /* Raw syscall, user-provided errno (send in 0 if you don't want it).  This is
  * usually used by code that can't handle errno (TLS). */
 long __ros_syscall(unsigned int _num, long _a0, long _a1, long _a2, long _a3,
@@ -33,6 +36,7 @@ long __ros_syscall_errno(unsigned int _num, long _a0, long _a1, long _a2,
 
 /* Bypass PLT when invoked from within libc */
 #ifdef libc_hidden_proto
+libc_hidden_proto(ros_syscall_sync)
 libc_hidden_proto(__ros_syscall)
 libc_hidden_proto(__ros_syscall_errno)
 #endif
index 4050035..eacf305 100644 (file)
@@ -88,6 +88,22 @@ void __ros_scp_syscall_blockon(struct syscall *sysc)
  * blockon before becoming an MCP.  Default is the glibc SCP handler */
 void (*ros_syscall_blockon)(struct syscall *sysc) = __ros_scp_syscall_blockon;
 
+/* Issue a single syscall and block into the 2LS until it completes */
+void ros_syscall_sync(struct syscall *sysc)
+{
+       /* There is only one syscall in the syscall array when we want to do it
+       * synchronously */
+       __ros_arch_syscall((long)sysc, 1);
+       /* Don't proceed til we are done */
+       while (!(atomic_read(&sysc->flags) & SC_DONE))
+               ros_syscall_blockon(sysc);
+       /* Need to wait til it is unlocked.  It's not really done until SC_DONE &
+        * !SC_K_LOCK. */
+       while (atomic_read(&sysc->flags) & SC_K_LOCK)
+               cpu_relax();
+}
+libc_hidden_def(ros_syscall_sync)
+
 /* 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
@@ -96,7 +112,6 @@ static inline struct syscall
 __ros_syscall_inline(unsigned int _num, long _a0, long _a1, long _a2, long _a3,
                      long _a4, long _a5)
 {
-       int num_started;        /* not used yet */
        struct syscall sysc = {0};
        sysc.num = _num;
        sysc.ev_q = 0;
@@ -106,14 +121,7 @@ __ros_syscall_inline(unsigned int _num, long _a0, long _a1, long _a2, long _a3,
        sysc.arg3 = _a3;
        sysc.arg4 = _a4;
        sysc.arg5 = _a5;
-       num_started = __ros_arch_syscall(&sysc, 1);
-       /* Don't proceed til we are done */
-       while (!(atomic_read(&sysc.flags) & SC_DONE))
-               ros_syscall_blockon(&sysc);
-       /* Need to wait til it is unlocked.  It's not really done until SC_DONE &
-        * !SC_K_LOCK. */
-       while (atomic_read(&sysc.flags) & SC_K_LOCK)
-               cpu_relax();
+    ros_syscall_sync(&sysc);
        return sysc;
 }