Async call responses
authorBarret Rhoden <brho@cs.berkeley.edu>
Sat, 9 May 2009 02:48:35 +0000 (19:48 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Sat, 9 May 2009 02:56:52 +0000 (19:56 -0700)
Pass back some sort of response from the syscalls within an async call.
Could consider passing in a function that does the aggregation of
responses, since it may be syscall specific.

Also, process_syscalls no longer resets the machine when trying to
process the syscalls of a process that's been freed.  Though there is no
sync protection with that yet.

inc/measure.h
kern/syscall.c
kern/syscall.h
lib/asynccall.c
lib/null.c

index 9f45058..78edc87 100644 (file)
@@ -33,7 +33,8 @@
        uint64_t ticks;                                                            \
        _desc_type* desc_array[i_iters];                                           \
        _desc_type* desc_name;                                                     \
-       _rsp_type* rsp;                                                            \
+       /* Could use an array of rsps, but we're throwing away the responses*/     \
+       _rsp_type rsp;                                                             \
        cpuid(0, 0, 0, 0, 0);                                                      \
        ticks = read_tsc();                                                        \
        /* Run this a bunch of times to make sure its accurate */                  \
@@ -43,7 +44,7 @@
                        desc_array[j] = desc_name;                                         \
                }                                                                      \
                for (int j = 0; j < (i_iters); j++) {                                  \
-                       wait_func(desc_array[j], rsp);                                     \
+                       wait_func(desc_array[j], &rsp);                                    \
                }                                                                      \
        }                                                                          \
        cpuid(0, 0, 0, 0, 0);                                                      \
index 993e598..fb733d7 100644 (file)
@@ -80,8 +80,8 @@ sys_env_destroy(envid_t envid)
 
 
 // Dispatches to the correct kernel function, passing the arguments.
-uint32_t
-syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
+int32_t syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3,
+                uint32_t a4, uint32_t a5)
 {
        // Call the function corresponding to the 'syscallno' parameter.
        // Return any appropriate return value.
@@ -97,7 +97,7 @@ syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4,
                        return 0;
                case SYS_cputs:
                        sys_cputs((char *DANGEROUS)a1, (size_t)a2);
-                       return 0;
+                       return 0;  // would rather have this return the number of chars put.
                case SYS_cgetc:
                        return sys_cgetc();
                case SYS_getenvid:
@@ -111,7 +111,7 @@ syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4,
        return 0xdeadbeef;
 }
 
-uint32_t syscall_async(syscall_req_t *call)
+int32_t syscall_async(syscall_req_t *call)
 {
        return syscall(call->num, call->args[0], call->args[1],
                       call->args[2], call->args[3], call->args[4]);
@@ -122,6 +122,11 @@ uint32_t process_generic_syscalls(env_t* e, uint32_t max)
        uint32_t count = 0;
        syscall_back_ring_t* sysbr = &e->env_sysbackring;
 
+       // make sure the env is still alive.  TODO: this cannot handle an env being
+       // freed async while this is processing.  (need a ref count or lock, etc).
+       if (e->env_status == ENV_FREE)
+               return 0;
+
        // need to switch to the right context, so we can handle the user pointer
        // that points to a data payload of the syscall
        lcr3(e->env_cr3);
index 1cc829c..9fcadd3 100644 (file)
@@ -7,9 +7,9 @@
 #include <inc/syscall.h>
 #include <inc/env.h>
 
-uint32_t (SYNCHRONOUS syscall)(uint32_t num, uint32_t a1, uint32_t a2,
+int32_t (SYNCHRONOUS syscall)(uint32_t num, uint32_t a1, uint32_t a2,
                                uint32_t a3, uint32_t a4, uint32_t a5);
-uint32_t syscall_async(syscall_req_t *syscall);
+int32_t syscall_async(syscall_req_t *syscall);
 uint32_t process_generic_syscalls(env_t* e, uint32_t max);
 
 #endif /* !ROS_KERN_SYSCALL_H */
index ae6065e..de5bbb2 100644 (file)
@@ -13,14 +13,18 @@ async_desc_t* get_async_desc(void)
 
 error_t waiton_async_call(async_desc_t* desc, async_rsp_t* rsp)
 {
-       // TODO: Fill in the rsp parameter passed in here with 
-       // something meaningful
        syscall_rsp_t syscall_rsp;
        syscall_desc_t* d;
        while (!(LIST_EMPTY(&desc->syslist))) {
                d = LIST_FIRST(&desc->syslist);
                waiton_syscall(d, &syscall_rsp);
-               // consider processing the retval out of rsp here (TODO)
+               // TODO: processing the retval out of rsp here.  might be specific to
+               // the async call.  do we want to accumulate?  return any negative
+               // values?  depends what we want from the return value, so we might
+               // have to pass in a function that is used to do the processing and
+               // pass the answer back out in rsp.
+               //rsp->retval += syscall_rsp.retval; // For example
+               rsp->retval = MIN(rsp->retval, syscall_rsp.retval);
                // remove from the list and free the syscall desc
                LIST_REMOVE(d, next);
                POOL_PUT(&syscall_desc_pool, d);
index b5d0db0..00a2aa5 100644 (file)
@@ -1,6 +1,3 @@
-// Simple implementation of cprintf console output for the kernel,
-// based on printfmt() and the kernel console's cputchar().
-
 #ifdef __DEPUTY__
 #pragma nodeputy
 #endif