Cleanup functions for syscalls
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 7 May 2009 07:39:31 +0000 (00:39 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 7 May 2009 07:39:31 +0000 (00:39 -0700)
inc/lib.h
inc/pool.h
inc/syscall.h
lib/printf.c
lib/syscall.c

index d0dd09c..a4893fc 100644 (file)
--- a/inc/lib.h
+++ b/inc/lib.h
@@ -38,7 +38,8 @@ char* readline(const char *buf);
 // syscall.c
 void sys_null();
 void sys_cputs(const char *string, size_t len);
-void sys_cputs_async(const char *string, size_t len, syscall_desc_t* desc);
+void sys_cputs_async(const char *s, size_t len, syscall_desc_t* desc,
+                     void (*cleanup_handler)(void*), void* cleanup_data);
 int    sys_cgetc(void);
 envid_t        sys_getenvid(void);
 int    sys_env_destroy(envid_t);
index 46c8733..68dcfa1 100644 (file)
@@ -4,6 +4,8 @@
 #ifndef ROS_INC_POOL_H
 #define ROS_INC_POOL_H   
 
+#include <inc/string.h>
+
 #define POOL_TYPE_DEFINE(_type, p, sz)                                                \
 typedef struct struct_##p {                                                             \
        uint32_t size;                                                         \
@@ -18,6 +20,7 @@ typedef struct struct_##p {
        (p)->size = (sz);                                                          \
        (p)->free = (sz);                                                          \
        (p)->index = 0;                                                            \
+       memset((p)->pool, 0, (sz) * sizeof((p)->pool[0]));                         \
        for(int i=0; i<(p)->size; i++) {                                           \
                (p)->queue[i] = &((p)->pool[i]);                                       \
        }                                                                          \
@@ -54,7 +57,7 @@ typedef struct struct_##p {
 })
 
 #define POOL_EMPTY(p) ((p)->free == 0)
-#define POOL_SIZE(p) ((p)->free))
-#define POOL_MAX_SIZE(p) ((p)->size))
+#define POOL_SIZE(p) ((p)->free)
+#define POOL_MAX_SIZE(p) ((p)->size)
 
 #endif //ROS_INC_POOL_H
index 85c8c02..81b88cd 100644 (file)
@@ -37,6 +37,9 @@ struct syscall_desc {
        LIST_ENTRY(syscall_desc_t) next;
        syscall_front_ring_t* sysfr;
        uint32_t idx;
+       // cleanup
+       void (*cleanup)(void* data);
+       void* data;
 };
 LIST_HEAD(syscall_desc_list_t, syscall_desc_t); 
 
index e1bc29a..ada1beb 100644 (file)
@@ -74,18 +74,23 @@ static error_t init_printf(void)
 static printbuf_t* get_free_buffer(void)
 {
        return POOL_GET(&print_buf_pool);
-       //cprintf("Out of buffers!!!\n");
 }
 
-// this buffering is a minor pain in the ass....
-// TODO - it will be a pain in the ass to put the buffers back after we waited.
+// This is called when the syscall is waited on
+static void cputs_async_cleanup(void* data)
+{
+       POOL_PUT(&print_buf_pool, (printbuf_t*)data);
+}
+
 static void putch_async(int ch, printbuf_t *b)
 {
        b->buf[b->idx++] = ch;
        if (b->idx == 256-1) {
                // will need some way to track the result of the syscall
-               sys_cputs_async(b->buf, b->idx, get_sys_desc(current_async_desc));
+               sys_cputs_async(b->buf, b->idx, get_sys_desc(current_async_desc),
+                               cputs_async_cleanup, b); 
                // TODO - this isn't getting passed back properly
+               // TODO - should check for a return value
                b = get_free_buffer();
                b->idx = 0;
        }
@@ -100,7 +105,8 @@ static int vcprintf_async(const char *fmt, va_list ap)
        b->idx = 0;
        b->cnt = 0;
        vprintfmt((void*)putch_async, b, fmt, ap);
-       sys_cputs_async(b->buf, b->idx, get_sys_desc(current_async_desc));
+       sys_cputs_async(b->buf, b->idx, get_sys_desc(current_async_desc),
+                       cputs_async_cleanup, b); 
 
        return b->cnt; // this is lying if we used more than one buffer
 }
@@ -117,6 +123,8 @@ int cprintf_async(async_desc_t** desc, const char *fmt, ...)
        current_async_desc = get_async_desc();
        *desc = current_async_desc;
 
+       cprintf("Pool size: %d\n", POOL_SIZE(&print_buf_pool));
+
        va_start(ap, fmt);
        cnt = vcprintf_async(fmt, ap);
        va_end(ap);
index 3b5548e..0123620 100644 (file)
@@ -65,13 +65,19 @@ error_t waiton_syscall(syscall_desc_t* desc, syscall_rsp_t* rsp)
                cpu_relax();
        memcpy(rsp, RING_GET_RESPONSE(desc->sysfr, desc->idx), sizeof(*rsp));
        desc->sysfr->rsp_cons++;
+    // run a cleanup function for this desc, if available
+    if (desc->cleanup)
+       desc->cleanup(desc->data);
        return 0;
 }
 
-void sys_cputs_async(const char *s, size_t len, syscall_desc_t* desc)
+void sys_cputs_async(const char *s, size_t len, syscall_desc_t* desc,
+                     void (*cleanup_handler)(void*), void* cleanup_data)
 {
        // could just hardcode 4 0's, will eventually wrap this marshaller anyway
        syscall_req_t syscall = {SYS_cputs, 0, {(uint32_t)s, len, [2 ... (NUM_SYS_ARGS-1)] 0} };
+       desc->cleanup = cleanup_handler;
+       desc->data = cleanup_data;
        async_syscall(&syscall, desc);
 }