Added an asynchronous sys_null_async() call and wrappers
authorKevin Klues <klueska@cs.berkeley.edu>
Fri, 8 May 2009 01:06:53 +0000 (18:06 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Fri, 8 May 2009 01:06:53 +0000 (18:06 -0700)
inc/lib.h
inc/measure.h
inc/null.h [new file with mode: 0644]
inc/syscall.h
lib/Makefrag
lib/asynccall.c
lib/null.c [new file with mode: 0644]
lib/syscall.c
user/hello.c
user/null.c

index 14e15d7..1741cf2 100644 (file)
--- a/inc/lib.h
+++ b/inc/lib.h
@@ -37,6 +37,7 @@ char* readline(const char *buf);
 
 // syscall.c
 void sys_null();
+void sys_null_async(syscall_desc_t* desc);
 void sys_cputs(const char *string, size_t len);
 void sys_cputs_async(const char *s, size_t len, syscall_desc_t* desc,
                      void (*cleanup_handler)(void*), void* cleanup_data);
@@ -54,6 +55,9 @@ typedef struct async_desc {
        void (*cleanup)(void* data);
        void* data;
 } async_desc_t;
+typedef struct async_rsp_t {
+       int32_t retval;
+} async_rsp_t;
 // This is per-thread, and used when entering a async library call to properly
 // group syscall_desc_t used during the processing of that async call
 extern async_desc_t* current_async_desc;
@@ -71,7 +75,7 @@ extern async_desc_pool_t async_desc_pool;
 // Finds a free async_desc_t, on which you can wait for a series of syscalls
 async_desc_t* get_async_desc(void);
 // Wait on all syscalls within this async call.  TODO - timeout or something?
-error_t waiton_async_call(async_desc_t* desc);
+error_t waiton_async_call(async_desc_t* desc, async_rsp_t* rsp);
 // Finds a free sys_desc_t, on which you can wait for a specific syscall, and
 // binds it to the group desc.
 syscall_desc_t* get_sys_desc(async_desc_t* desc);
index a751bb8..9f45058 100644 (file)
        ticks;                                                                     \
 })
 
-#define measure_function_async(func, desc_name, i_iters, o_iters, name)        \
+#define measure_function_async(func, _desc_type, _rsp_type, wait_func,         \
+                                  desc_name, i_iters, o_iters, name)              \
 ({                                                                             \
        uint64_t ticks;                                                            \
+       _desc_type* desc_array[i_iters];                                           \
+       _desc_type* desc_name;                                                     \
+       _rsp_type* rsp;                                                            \
        cpuid(0, 0, 0, 0, 0);                                                      \
        ticks = read_tsc();                                                        \
-       async_desc_t* desc_array[i_iters];                                         \
-       async_desc_t* desc_name;                                                   \
        /* Run this a bunch of times to make sure its accurate */                  \
        for(int i=0; i< (o_iters); i++) {                                          \
                for (int j = 0; j < (i_iters); j++) {                                  \
@@ -41,7 +43,7 @@
                        desc_array[j] = desc_name;                                         \
                }                                                                      \
                for (int j = 0; j < (i_iters); j++) {                                  \
-                       waiton_async_call(desc_array[j]);                                  \
+                       wait_func(desc_array[j], rsp);                                     \
                }                                                                      \
        }                                                                          \
        cpuid(0, 0, 0, 0, 0);                                                      \
@@ -58,4 +60,8 @@
        ticks;                                                                     \
 })
 
+#define measure_async_call(func, desc_name, i_iters, o_iters, name)            \
+       measure_function_async(func, async_desc_t, async_rsp_t, waiton_async_call, \
+                              desc_name, i_iters, o_iters, name)
+
 #endif /* !ROS_INC_MEASURE_H */
diff --git a/inc/null.h b/inc/null.h
new file mode 100644 (file)
index 0000000..6277484
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef ROS_INC_NULL_H
+#define ROS_INC_NULL_H
+
+void null();
+void null_async(async_desc_t** desc);
+
+#endif // ROS_INC_NULL_H
index 822ad02..2756ab3 100644 (file)
@@ -19,13 +19,13 @@ enum
 #define INVALID_SYSCALL(syscallno) ((syscallno) > NSYSCALLS)
 
 #define NUM_SYS_ARGS 6
-typedef struct SyscallRequest {
+typedef struct syscall_req {
        uint32_t num;
        uint32_t flags;
        uint32_t args[NUM_SYS_ARGS];
 } syscall_req_t;
 
-typedef struct SyscallResponse {
+typedef struct syscall_rsp {
        int32_t retval;
 } syscall_rsp_t;
 
index 0382476..19799ea 100644 (file)
@@ -4,6 +4,7 @@ OBJDIRS += lib
 
 LIB_SRCFILES :=                lib/console.c \
                        lib/libmain.c \
+                       lib/null.c \
                        lib/exit.c \
                        lib/panic.c \
                        lib/printf.c \
index e5d7ba0..ae6065e 100644 (file)
@@ -11,13 +11,15 @@ async_desc_t* get_async_desc(void)
        return desc;
 }
 
-error_t waiton_async_call(async_desc_t* desc)
+error_t waiton_async_call(async_desc_t* desc, async_rsp_t* rsp)
 {
-       syscall_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, &rsp);
+               waiton_syscall(d, &syscall_rsp);
                // consider processing the retval out of rsp here (TODO)
                // remove from the list and free the syscall desc
                LIST_REMOVE(d, next);
diff --git a/lib/null.c b/lib/null.c
new file mode 100644 (file)
index 0000000..b5d0db0
--- /dev/null
@@ -0,0 +1,22 @@
+// Simple implementation of cprintf console output for the kernel,
+// based on printfmt() and the kernel console's cputchar().
+
+#ifdef __DEPUTY__
+#pragma nodeputy
+#endif
+
+#include <inc/types.h>
+#include <inc/syscall.h>
+#include <inc/lib.h>
+
+void null()
+{
+       sys_null();
+}
+
+void null_async(async_desc_t** desc)
+{
+       current_async_desc = get_async_desc();
+       *desc = current_async_desc;
+       sys_null_async(get_sys_desc(current_async_desc));
+}
index 2abfa97..7f1faf8 100644 (file)
@@ -71,6 +71,14 @@ error_t waiton_syscall(syscall_desc_t* desc, syscall_rsp_t* rsp)
        return 0;
 }
 
+void sys_null_async(syscall_desc_t* desc)
+{
+       syscall_req_t syscall = {SYS_null, 0, {[0 ... (NUM_SYS_ARGS-1)] 0}};
+       desc->cleanup = NULL;
+       desc->data = NULL;
+       async_syscall(&syscall, desc);
+}
+
 void sys_cputs_async(const char *s, size_t len, syscall_desc_t* desc,
                      void (*cleanup_handler)(void*), void* cleanup_data)
 {
index 8ff24e6..e79c45e 100644 (file)
@@ -18,17 +18,19 @@ void umain(void)
        // will be the one printed when the syscall is serviced, regardless of
        // whether the actual syscall can handle multiples in flight.
        async_desc_t *desc1, *desc2, *desc3;
+       async_desc_t rsp1, rsp2, rsp3;
        cprintf_async(&desc1, "Cross-Core call 1, coming from env %08x\n", env->env_id);
        cprintf("Call 1 is sent!\n");
        //cprintf_async(&desc2, "Cross-Core call 2, coming from env %08x\n", env->env_id);
        cprintf_async(&desc2, "1111111111111111111111111111111122222222222222222222222222222222333333333333333333333333333333334444444444444444444444444444444455555555555555555555555555555555666666666666666666666666666666667777777777777777777777777777777788888888888888888888888888888888Cross-Core call 2, coming from env %08x\n", env->env_id);
        cprintf("Call 2 is sent!\n");
        cprintf("Waiting on Call 1 and 2\n");
-       waiton_async_call(desc1);
+       waiton_async_call(desc1, &rsp1);
        cprintf("Received 1\n");
-       waiton_async_call(desc2);
+       waiton_async_call(desc2, &rsp2);
        cprintf_async(&desc3, "Cross-Core call 3, coming from env %08x\n", env->env_id);
        cprintf("Call 3 is sent!\n");
+       waiton_async_call(desc3, &rsp3);
        // might as well spin, just to make sure nothing gets deallocated
        // while we're waiting to test the async call
        while (1);
index 108a126..b91186e 100644 (file)
@@ -4,6 +4,7 @@
 #include <inc/syscall.h>
 #include <inc/x86.h>
 #include <inc/measure.h>
+#include <inc/null.h>
 
 #ifdef __DEPUTY__
 #pragma nodeputy
@@ -28,7 +29,8 @@ void umain(void)
        measure_function(asm volatile("nop;"), NUM_ITERATIONS, "nop");
        //measure_function(cprintf("Reg Sync call  \n"), 10, "printf");
        //measure_function_async(cprintf_async(&desc, "Cross-Core call\n"), desc, 10,\
-                              1, "Async Printf");
+       //                       1, "Async Printf");
+       measure_async_call(null_async(&desc), desc, 10, 1, "Async Null");
 
        // Spin to make sure we don't have any resources deallocated before done
        while(1);