Initial implementation of timer pool and timer tag
authorDavid Zhu <yuzhu@cs.berkeley.edu>
Fri, 22 May 2009 03:18:35 +0000 (20:18 -0700)
committerDavid Zhu <yuzhu@cs.berkeley.edu>
Fri, 22 May 2009 03:18:35 +0000 (20:18 -0700)
Each function can call function begin and end macros to do single run measurement and aggregate measurement.
At the end of the run, we can go through the timer pool to print out each timer measurement.

inc/lib.h
inc/pool.h
inc/timer.h [new file with mode: 0644]
kern/Makefrag
kern/apic.c
lib/Makefrag
lib/libmain.c
lib/timer.c [new file with mode: 0644]
user/null.c

index b6abbbe..5813e47 100644 (file)
--- a/inc/lib.h
+++ b/inc/lib.h
@@ -15,6 +15,7 @@
 #include <inc/memlayout.h>
 #include <inc/syscall.h>
 #include <inc/pool.h>
+#include <inc/timer.h>
 // These two are included below because of dependency issues.
 //#include <inc/stdio.h>
 //#include <inc/assert.h>
@@ -76,9 +77,13 @@ extern async_desc_t* current_async_desc;
 POOL_TYPE_DEFINE(syscall_desc_t, syscall_desc_pool, MAX_SYSCALLS);
 POOL_TYPE_DEFINE(async_desc_t, async_desc_pool, MAX_ASYNCCALLS);
 
+// This pooltype contains all the timers used in user level time tracking
+POOL_TYPE_DEFINE(timer_t, timer_pool, MAX_TIMERS);
+
 // These are declared in libmain.c
 extern syscall_desc_pool_t syscall_desc_pool;
 extern async_desc_pool_t async_desc_pool;
+extern timer_pool_t timer_pool;
 
 error_t waiton_async_call(async_desc_t* desc, async_rsp_t* rsp);
 async_desc_t* get_async_desc(void);
index 31d9d3b..36607ec 100644 (file)
@@ -41,6 +41,19 @@ typedef struct struct_##p {
        rval;                                                      \
 })
 
+// emptyIndex is also the first element that has been allocated, iterate thru to index-1
+
+#define POOL_FOR_EACH(p, func)                                                                 \
+({                                                                                                                             \
+       int emptyIndex = ((p)->index + (p)->free);                  \
+       if (emptyIndex >= (p)->size) {                                          \
+               emptyIndex -= (p)->size;                                        \
+       }                                                                   \
+       for(int _i = emptyIndex;  _i < (p)->index; _i++){                       \
+               func((p)->queue[_i]);                                                                   \
+       }                                                                                                                       \
+})                                                                                                                             \
+
 #define POOL_PUT(p, val)                                                       \
 ({                                                                             \
        int rval = -1;                                                            \
diff --git a/inc/timer.h b/inc/timer.h
new file mode 100644 (file)
index 0000000..e40e308
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef ROS_INC_TIMER_H
+#define ROS_INC_TIMER_H
+#include <inc/pool.h>
+#include <inc/string.h>
+
+#define TIMER_TAG_SIZE 20
+#define MAX_TIMERS 20
+
+typedef struct Timer{
+       uint64_t curr_run;
+       uint64_t aggr_run;
+       char label[TIMER_TAG_SIZE];
+} timer_t;
+
+// vanilla variety
+uint64_t start_timing() __attribute__((noinline));
+uint64_t stop_timing(uint64_t val, uint64_t overhead) __attribute__((noinline));
+//void print_timerpool(
+//allocate if not null
+//starttiming
+//stoptiming
+#define FUNCBEGIN(tag)                                                 \
+static timer_t*  _timer_##tag = 0;                             \
+if (_timer_##tag == NULL){                                             \
+       _timer_##tag = POOL_GET(&timer_pool);           \
+       strcpy((_timer_##tag->label), #tag);            \
+       _timer_##tag->aggr_run = 0;                                     \
+}                                                                                              \
+_timer_##tag->curr_run = start_timing();
+
+
+#define FUNCEND(tag)                                                                                                           \
+({                                                                                                                                                     \
+_timer_##tag->curr_run = stop_timing(_timer_##tag->curr_run, 0);                       \
+_timer_##tag->aggr_run += _timer_##tag->curr_run;                                                      \
+})
+
+
+
+
+#endif /* !ROS_INC_TIMER_H */
+
index 497bbba..74e8a3b 100644 (file)
@@ -35,7 +35,8 @@ KERN_SRCFILES :=      kern/entry.S \
                        kern/smp.c \
                        lib/printfmt.c \
                        lib/readline.c \
-                       lib/string.c
+                       lib/string.c \
+                       lib/timer.c
 
 # Only build files if they exist.
 KERN_SRCFILES := $(wildcard $(KERN_SRCFILES))
index 4e79d26..9c20f43 100644 (file)
@@ -6,6 +6,7 @@
 #include <inc/mmu.h>
 #include <inc/x86.h>
 #include <inc/assert.h>
+#include <inc/timer.h>
 
 #include <kern/apic.h>
 
@@ -92,22 +93,6 @@ uint32_t lapic_get_default_id(void)
        return (ebx & 0xFF000000) >> 24;
 }
 
-uint64_t read_tsc_serialized() __attribute__((noinline)) 
-{
-       cpuid(0, 0, 0, 0, 0);
-       return read_tsc();
-}
-
-uint64_t start_timing() __attribute__((noinline)) 
-{
-       return read_tsc_serialized();
-}
-
-uint64_t stop_timing(uint64_t val) __attribute__((noinline)) 
-{
-       return (read_tsc_serialized() - val - timing_overhead);
-}
-
 void train_timing() 
 {
        uint16_t num_runs = 0;
@@ -122,7 +107,7 @@ void train_timing()
                 */
                for(int i=0; i<100; i++) {
                        uint64_t time = start_timing();
-                       uint64_t diff = stop_timing(time);
+                       uint64_t diff = stop_timing(time, timing_overhead);
                        
                        /* In case diff was negative, I want to add its absolute value
                         * to the cumulative error, otherwise, just diff itself
index 19799ea..3ec563d 100644 (file)
@@ -12,7 +12,8 @@ LIB_SRCFILES :=               lib/console.c \
                        lib/readline.c \
                        lib/string.c \
                        lib/syscall.c \
-                       lib/asynccall.c
+                       lib/asynccall.c \
+                       lib/timer.c
 
 
 
index 3dd0899..e0ce63e 100644 (file)
@@ -11,6 +11,8 @@ char *binaryname = "(PROGRAM NAME UNKNOWN)";
 syscall_front_ring_t sysfrontring;
 syscall_desc_pool_t syscall_desc_pool;
 async_desc_pool_t async_desc_pool;
+timer_pool_t timer_pool;
+
 // This is meant to be PER USER THREAD!!! (TODO (benh))
 async_desc_t* current_async_desc;
 
@@ -20,13 +22,17 @@ libmain(int argc, char **argv)
        // set env to point at our env structure in envs[].
        // TODO: for now, the kernel just copies our env struct to the beginning of
        // procinfo.  When we figure out what we want there, change this.
-       env = (env_t*)procinfo;
+       env = (env_t*)procinfo; 
 
        // Set up the front ring for the general syscall ring
+       // TODO: Reorganize these global variables
        FRONT_RING_INIT(&sysfrontring, (syscall_sring_t*)procdata, PGSIZE);
        POOL_INIT(&syscall_desc_pool, MAX_SYSCALLS);
        POOL_INIT(&async_desc_pool, MAX_ASYNCCALLS);
 
+       // Setup the timer pool 
+       POOL_INIT(&timer_pool, MAX_TIMERS);
+
        // save the name of the program so that panic() can use it
        if (argc > 0)
                binaryname = argv[0];
diff --git a/lib/timer.c b/lib/timer.c
new file mode 100644 (file)
index 0000000..6498e36
--- /dev/null
@@ -0,0 +1,20 @@
+#include <inc/x86.h>
+#include <inc/timer.h>
+
+// TODO: export timing_overhead to user level 
+
+uint64_t read_tsc_serialized() __attribute__((noinline)) 
+{
+       cpuid(0, 0, 0, 0, 0);
+       return read_tsc();
+}
+
+uint64_t start_timing() __attribute__((noinline)) 
+{
+       return read_tsc_serialized();
+}
+
+uint64_t stop_timing(uint64_t val, uint64_t overhead) __attribute__((noinline)) 
+{
+       return (read_tsc_serialized() - val - overhead);
+}
index 6eddeae..4b7587a 100644 (file)
@@ -5,6 +5,7 @@
 #include <inc/x86.h>
 #include <inc/measure.h>
 #include <inc/null.h>
+#include <inc/timer.h>
 
 #ifdef __DEPUTY__
 #pragma nodeputy
@@ -25,6 +26,7 @@ uint64_t total(uint64_t (COUNT(length) array)[], int length)
 
 void umain(void)
 {
+       FUNCBEGIN(tst);
        async_desc_t *desc1, *desc2;
        async_rsp_t rsp1, rsp2;
        cache_buster_async(&desc1, 20, 0xdeadbeef);
@@ -39,7 +41,8 @@ void umain(void)
        // Note this won't actually do 100 inner runs (first parameter).  will stop
        // making calls beyond the ring size and won't wait on any extra calls.
        measure_async_call(null_async(&desc), desc, 100, 100, "Async Null");
-
+       
+       FUNCEND(tst);
        // Spin to make sure we don't have any resources deallocated before done
        while(1);
 }