parlib: slab: Use the modern ctor/dtor interface
[akaros.git] / user / parlib / syscall.c
index 08bcedb..aaf3a1c 100644 (file)
@@ -1,32 +1,21 @@
 // System call stubs.
 
-#include <parlib.h>
+#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)
 {
        return ros_syscall(SYS_proc_destroy, pid, exitcode, 0, 0, 0, 0);
 }
 
-int sys_getpid(void)
-{
-        return ros_syscall(SYS_getpid, 0, 0, 0, 0, 0, 0);
-}
-
 size_t sys_getpcoreid(void)
 {
         return ros_syscall(SYS_getpcoreid, 0, 0, 0, 0, 0, 0);
 }
 
-ssize_t sys_cputs(const uint8_t *s, size_t len)
-{
-    return ros_syscall(SYS_cputs, s,  len, 0, 0, 0, 0);
-}
-
-uint16_t sys_cgetc(void)
-{
-    return ros_syscall(SYS_cgetc, 0, 0, 0, 0, 0, 0);
-}
-
 int sys_null(void)
 {
     return ros_syscall(SYS_null, 0, 0, 0, 0, 0, 0);
@@ -45,36 +34,6 @@ ssize_t sys_shared_page_free(void* addr, pid_t p2)
        return ros_syscall(SYS_shared_page_free, addr, p2, 0, 0, 0, 0);
 }
 
-//Write a buffer over the serial port
-ssize_t sys_serial_write(void* buf, size_t len) 
-{
-       return ros_syscall(SYS_serial_write, buf, len, 0, 0, 0, 0);
-}
-
-//Read a buffer over the serial port
-ssize_t sys_serial_read(void* buf, size_t len) 
-{
-       return ros_syscall(SYS_serial_read, buf, len, 0, 0, 0, 0);
-}
-
-//Write a buffer over ethernet
-ssize_t sys_eth_write(void* buf, size_t len) 
-{
-       if (len == 0)
-               return 0;
-       
-       return ros_syscall(SYS_eth_write, buf, len, 0, 0, 0, 0);
-}
-
-//Read a buffer via ethernet
-ssize_t sys_eth_read(void* buf, size_t len) 
-{
-       if (len == 0)
-               return 0;
-               
-       return ros_syscall(SYS_eth_read, buf, len, 0, 0, 0, 0);
-}
-
 void sys_reboot(void)
 {
        ros_syscall(SYS_reboot, 0, 0, 0, 0, 0, 0);
@@ -82,17 +41,21 @@ 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(char *path, size_t path_l, char *argv[], char *envp[])
+int sys_proc_create(const char *path, size_t path_l, char *const argv[],
+                    char *const envp[], int flags)
 {
-       struct procinfo pi;
-       if (procinfo_pack_args(&pi, argv, envp)) {
+       struct serialized_data *sd = serialize_argv_envp(argv, envp);
+       if (!sd) {
                errno = ENOMEM;
                return -1;
        }
-       return ros_syscall(SYS_proc_create, path, path_l, &pi, 0, 0, 0);
+       int ret = ros_syscall(SYS_proc_create, path, path_l,
+                             sd->buf, sd->len, flags, 0);
+       free_serialized_data(sd);
+       return ret;
 }
 
 int sys_proc_run(int pid)
@@ -100,12 +63,17 @@ int sys_proc_run(int pid)
        return ros_syscall(SYS_proc_run, pid, 0, 0, 0, 0, 0);
 }
 
-void *CT(length) sys_mmap(void *SNT addr, size_t length, int prot, int flags,
-                          int fd, size_t offset)
+void *sys_mmap(void *addr, size_t length, int prot, int flags,
+               int fd, size_t offset)
 {
        return (void*)ros_syscall(SYS_mmap, addr, length, prot, flags, fd, offset);
 }
 
+int sys_provision(int pid, unsigned int res_type, long res_val)
+{
+       return ros_syscall(SYS_provision, pid, res_type, res_val, 0, 0, 0);
+}
+
 int sys_notify(int pid, unsigned int ev_type, struct event_msg *u_msg)
 {
        return ros_syscall(SYS_notify, pid, ev_type, u_msg, 0, 0, 0);
@@ -117,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);
 }
@@ -127,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);
 }
@@ -148,7 +122,35 @@ int sys_block(unsigned int usec)
  *             -EINVAL some userspace bug */
 int sys_change_vcore(uint32_t vcoreid, bool enable_my_notif)
 {
-       return ros_syscall(SYS_change_vcore, vcoreid, enable_my_notif, 0, 0, 0, 0);
+       /* Since we might be asking to start up on a fresh stack (if
+        * enable_my_notif), we need to use some non-stack memory for the struct
+        * sysc.  Our vcore could get restarted before the syscall finishes (after
+        * 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. */
+       do {
+               cpu_relax();
+               flags = atomic_read(&__vcore_one_sysc.flags);
+       } while (!(flags & SC_DONE) || flags & SC_K_LOCK);
+       __vcore_one_sysc.num = SYS_change_vcore;
+       __vcore_one_sysc.arg0 = vcoreid;
+       __vcore_one_sysc.arg1 = enable_my_notif;
+       /* keep in sync with glibc sysdeps/ros/syscall.c */
+       __ros_arch_syscall((long)&__vcore_one_sysc, 1);
+       /* If we returned, either we wanted to (!enable_my_notif) or we failed.
+        * Need to wait til the sysc is finished to find out why.  Again, its okay
+        * to just spin. */
+       do {
+               cpu_relax();
+               flags = atomic_read(&__vcore_one_sysc.flags);
+       } while (!(flags & SC_DONE) || flags & SC_K_LOCK);
+       return __vcore_one_sysc.retval;
 }
 
 int sys_change_to_m(void)
@@ -156,7 +158,63 @@ int sys_change_to_m(void)
        return ros_syscall(SYS_change_to_m, 0, 0, 0, 0, 0, 0);
 }
 
-int sys_poke_ksched(int res_type)
+int sys_poke_ksched(int pid, unsigned int res_type)
+{
+       return ros_syscall(SYS_poke_ksched, pid, res_type, 0, 0, 0, 0);
+}
+
+int sys_abort_sysc(struct syscall *sysc)
+{
+       return ros_syscall(SYS_abort_sysc, sysc, 0, 0, 0, 0, 0);
+}
+
+int sys_abort_sysc_fd(int fd)
 {
-       return ros_syscall(SYS_poke_ksched, res_type, 0, 0, 0, 0, 0);
+       return ros_syscall(SYS_abort_sysc_fd, fd, 0, 0, 0, 0, 0);
+}
+
+int sys_tap_fds(struct fd_tap_req *tap_reqs, size_t nr_reqs)
+{
+       return ros_syscall(SYS_tap_fds, tap_reqs, nr_reqs, 0, 0, 0, 0);
+}
+
+void syscall_async(struct syscall *sysc, unsigned long num, ...)
+{
+       va_list args;
+
+       sysc->num = num;
+       sysc->flags = 0;
+       sysc->ev_q = 0;         /* not necessary, but good for debugging */
+       /* 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);
+}
+
+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);
 }