Added cache_buster syscall
authorBarret Rhoden <brho@cs.berkeley.edu>
Tue, 26 May 2009 03:05:07 +0000 (20:05 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 5 Jun 2009 23:52:57 +0000 (16:52 -0700)
The cache-buster syscall takes a few more options, so we don't have
to change it to run a different test.  Also changed the roslib syscall
wrappers to have a meaningful name.

include/ros/syscall.h
kern/src/syscall.c
user/apps/roslib/print_tests.c
user/roslib/inc/lib.h
user/roslib/inc/measure.h
user/roslib/inc/null.h [deleted file]
user/roslib/inc/syswrapper.h [new file with mode: 0644]
user/roslib/src/Makefrag
user/roslib/src/null.c [deleted file]
user/roslib/src/syscall.c
user/roslib/src/syswrapper.c [new file with mode: 0644]

index da15bd4..521acc0 100644 (file)
@@ -27,12 +27,12 @@ enum
 // syscall number starts at 1 and goes up to NSYSCALLS, without holes.
 #define INVALID_SYSCALL(syscallno) ((syscallno) > NSYSCALLS)
 
-//intreg_t syscall_sysenter(uint16_t num, intreg_t a1,
-//                          intreg_t a2, intreg_t a3,
-//                          intreg_t a4, intreg_t a5);
-int32_t syscall_sysenter(uint16_t num, int32_t a1,
-                         int32_t a2, int32_t a3,
-                         int32_t a4, int32_t a5);
+/* For Buster Measurement Flags */
+#define BUSTER_SHARED                  0x0001
+#define BUSTER_STRIDED                 0x0002
+#define BUSTER_LOCKED                  0x0004
+#define BUSTER_PRINT_TICKS             0x0008
+#define BUSTER_JUST_LOCKS              0x0010 // unimplemented
 
 #define NUM_SYS_ARGS 6
 typedef struct syscall_req {
index 784b4c2..cb3ded8 100644 (file)
@@ -7,7 +7,9 @@
 #include <arch/x86.h>
 #include <arch/console.h>
 #include <arch/apic.h>
+#include <arch/timer.h>
 #include <ros/error.h>
+
 #include <string.h>
 #include <assert.h>
 #include <env.h>
@@ -69,17 +71,72 @@ static void sys_cache_invalidate(void)
 // address space.  It's just #defined to be some random 4MB chunk (which ought
 // to be boot_alloced or something).  Meant to grab exclusive access to cache
 // lines, to simulate doing something useful.
-static void sys_cache_buster(env_t* e, uint32_t num_writes, uint32_t val)
+static void sys_cache_buster(env_t* e, uint32_t num_writes, uint32_t num_pages,
+                             uint32_t flags)
 {
-       #define BUSTER_ADDR 0xd0000000
-       #define MAX_WRITES 1048576
+       #define BUSTER_ADDR             0xd0000000  // around 512 MB deep
+       #define MAX_WRITES              1048576*8
+       #define MAX_PAGES               32
+       #define INSERT_ADDR     (UINFO + 2*PGSIZE) // should be free for these tests
        uint32_t* buster = (uint32_t*)BUSTER_ADDR;
        static uint32_t buster_lock = 0;
+       uint64_t ticks;
+       page_t* a_page[MAX_PAGES];
+
+       /* Strided Accesses or Not (adjust to step by cachelines) */
+       uint32_t stride = 1;
+       if (flags & BUSTER_STRIDED) {
+               stride = 16;
+               num_writes *= 16;
+       }
+       
+       /* Shared Accesses or Not (adjust to use per-core regions)
+        * Careful, since this gives 8MB to each core, starting around 512MB.
+        * Also, doesn't separate memory for core 0 if it's an async call.
+        */
+       if (!(flags & BUSTER_SHARED))
+               buster = (uint32_t*)(BUSTER_ADDR + lapic_get_id() * 0x00800000);
+
+       /* Start the timer, if we're asked to print this info*/
+       if (flags & BUSTER_PRINT_TICKS)
+               ticks = start_timing();
+
+       /* Allocate num_pages (up to MAX_PAGES), to simulate doing some more
+        * realistic work.  Note we don't write to these pages, even if we pick
+        * unshared.  Mostly due to the inconvenience of having to match up the
+        * number of pages with the number of writes.  And it's unnecessary.
+        */
+       if (num_pages) {
+               spin_lock(&buster_lock);
+               for (int i = 0; i < MIN(num_pages, MAX_PAGES); i++) {
+                       page_alloc(&a_page[i]);
+                       page_insert(e->env_pgdir, a_page[i], (void*)INSERT_ADDR + PGSIZE*i,
+                                   PTE_U | PTE_W);
+               }
+               spin_unlock(&buster_lock);
+       }
+
+       if (flags & BUSTER_LOCKED)
+               spin_lock(&buster_lock);
+       for (int i = 0; i < MIN(num_writes, MAX_WRITES); i=i+stride)
+               buster[i] = 0xdeadbeef;
+       if (flags & BUSTER_LOCKED)
+               spin_unlock(&buster_lock);
+
+       if (num_pages) {
+               spin_lock(&buster_lock);
+               for (int i = 0; i < MIN(num_pages, MAX_PAGES); i++) {
+                       page_remove(e->env_pgdir, (void*)(INSERT_ADDR + PGSIZE * i));
+                       page_decref(a_page[i]);
+               }
+               spin_unlock(&buster_lock);
+       }
 
-       spin_lock(&buster_lock);
-       for (int i = 0; i < MIN(num_writes, MAX_WRITES); i++)
-               buster[i] = val;
-       spin_unlock(&buster_lock);
+       /* Print info */
+       if (flags & BUSTER_PRINT_TICKS) {
+               ticks = stop_timing(ticks);
+               printk("%llu,", ticks);
+       }
        return;
 }
 
@@ -174,7 +231,7 @@ intreg_t syscall(env_t* e, uint32_t syscallno, uint32_t a1, uint32_t a2,
                        sys_cache_invalidate();
                        return 0;
                case SYS_cache_buster:
-                       sys_cache_buster(e, a1, a2);
+                       sys_cache_buster(e, a1, a2, a3);
                        return 0;
                case SYS_cputs:
                        return sys_cputs(e, (char *DANGEROUS)a1, (size_t)a2);
index 0bbb6b7..3d1ff85 100644 (file)
@@ -1,5 +1,5 @@
 #include <inc/lib.h>
-#include <inc/null.h>
+#include <inc/syswrapper.h>
 
 #ifdef __DEPUTY__
 #pragma nodeputy
index fbded5e..26ceec0 100644 (file)
@@ -34,9 +34,10 @@ void exit(void) __attribute__((noreturn));
 void        sys_null();
 error_t     sys_null_async(syscall_desc_t* desc);
 void        sys_cache_invalidate();
-void        sys_cache_buster(uint32_t num_writes, uint32_t val);
-error_t     sys_cache_buster_async(syscall_desc_t* desc, 
-                                   uint32_t num_writes, uint32_t val);
+void        sys_cache_buster(uint32_t num_writes, uint32_t num_pages,
+                             uint32_t flags);
+error_t     sys_cache_buster_async(syscall_desc_t* desc, uint32_t num_writes,
+                                   uint32_t num_pages, uint32_t flags);
 ssize_t     sys_cputs(const char *string, size_t len);
 error_t     sys_cputs_async(const char *s, size_t len, syscall_desc_t* desc,
                             void (*cleanup_handler)(void*), void* cleanup_data);
index af228f9..9457c52 100644 (file)
@@ -1,10 +1,11 @@
 #ifndef ROS_INC_MEASURE_H
 #define ROS_INC_MEASURE_H
 
-#include <inc/types.h>
-#include <inc/stdio.h>
-#include <inc/timer.h>
-#include <inc/x86.h>
+#include <arch/types.h>
+#include <arch/timer.h>
+#include <arch/x86.h>
+
+#include <stdio.h>
 
 /* Macro for printing out debug information about our measurement setup.
  * If MEASURE_DEBUG is set to 1, debug info will be printed.  If set to 0
diff --git a/user/roslib/inc/null.h b/user/roslib/inc/null.h
deleted file mode 100644 (file)
index 7e1f763..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef ROS_INC_NULL_H
-#define ROS_INC_NULL_H
-
-void null();
-error_t null_async(async_desc_t** desc);
-void cache_buster(uint32_t num_writes, uint32_t val);
-error_t cache_buster_async(async_desc_t** desc, uint32_t num_writes,
-                           uint32_t val);
-uint32_t getcpuid(void);
-
-#endif // ROS_INC_NULL_H
diff --git a/user/roslib/inc/syswrapper.h b/user/roslib/inc/syswrapper.h
new file mode 100644 (file)
index 0000000..4cc24d7
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef ROS_INC_NULL_H
+#define ROS_INC_NULL_H
+
+void null();
+error_t null_async(async_desc_t** desc);
+void cache_buster(uint32_t num_writes, uint32_t num_pages, uint32_t flags);
+error_t cache_buster_async(async_desc_t** desc, uint32_t num_writes,
+                           uint32_t num_pages, uint32_t flags);
+uint32_t getcpuid(void);
+
+#endif // ROS_INC_NULL_H
index 3d7e35f..32fc0f3 100644 (file)
@@ -6,7 +6,7 @@ USER_ROSLIB_SRC_CFLAGS   := $(USER_CFLAGS) -nostdinc \
 
 USER_ROSLIB_SRC_SRCFILES := $(USER_ROSLIB_SRC_DIR)/console.c \
                             $(USER_ROSLIB_SRC_DIR)/libmain.c \
-                            $(USER_ROSLIB_SRC_DIR)/null.c \
+                            $(USER_ROSLIB_SRC_DIR)/syswrapper.c \
                             $(USER_ROSLIB_SRC_DIR)/exit.c \
                             $(USER_ROSLIB_SRC_DIR)/panic.c \
                             $(USER_ROSLIB_SRC_DIR)/printf.c \
diff --git a/user/roslib/src/null.c b/user/roslib/src/null.c
deleted file mode 100644 (file)
index 140c223..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifdef __DEPUTY__
-#pragma nodeputy
-#endif
-
-#include <types.h>
-#include <lib.h>
-#include <ros/syscall.h>
-
-void null()
-{
-       sys_null();
-}
-
-error_t null_async(async_desc_t** desc)
-{
-       error_t e;
-       syscall_desc_t* sysdesc;
-       if (e = get_all_desc(desc, &sysdesc))
-               return e;
-       return sys_null_async(sysdesc);
-}
-
-void cache_buster(uint32_t num_writes, uint32_t val)
-{
-       sys_cache_buster(num_writes, val);
-}
-
-error_t cache_buster_async(async_desc_t** desc, uint32_t num_writes, uint32_t val)
-{
-       error_t e;
-       syscall_desc_t* sysdesc;
-       if (e = get_all_desc(desc, &sysdesc))
-               return e;
-       return sys_cache_buster_async(sysdesc, num_writes, val);
-}
-
-uint32_t getcpuid(void)
-{
-       return sys_getcpuid();
-}
index ead316a..5977321 100644 (file)
@@ -130,16 +130,16 @@ error_t sys_null_async(syscall_desc_t* desc)
        return async_syscall(&syscall, desc);
 }
 
-void sys_cache_buster(uint32_t num_writes, uint32_t val)
+void sys_cache_buster(uint32_t num_writes, uint32_t num_pages, uint32_t flags)
 {
-       syscall(SYS_cache_buster, num_writes, val, 0, 0, 0);
+       syscall(SYS_cache_buster, num_writes, num_pages, flags, 0, 0);
 }
 
-error_t sys_cache_buster_async(syscall_desc_t* desc, uint32_t num_writes,
-                               uint32_t val)
+error_t        sys_cache_buster_async(syscall_desc_t* desc, uint32_t num_writes,
+                                              uint32_t num_pages, uint32_t flags)
 {
-       syscall_req_t syscall = {SYS_cache_buster, 0,
-                                {num_writes, val, [2 ... (NUM_SYS_ARGS-1)] 0}};
+       syscall_req_t syscall = {SYS_cache_buster, 0, {num_writes, num_pages, flags,
+                                                      [3 ... (NUM_SYS_ARGS-1)] 0}};
        // just to be safe, 0 these out.  they should have been 0'd right after
        // the desc was POOL_GET'd
        desc->cleanup = NULL;
diff --git a/user/roslib/src/syswrapper.c b/user/roslib/src/syswrapper.c
new file mode 100644 (file)
index 0000000..1078534
--- /dev/null
@@ -0,0 +1,41 @@
+#ifdef __DEPUTY__
+#pragma nodeputy
+#endif
+
+#include <types.h>
+#include <lib.h>
+#include <ros/syscall.h>
+
+void null()
+{
+       sys_null();
+}
+
+error_t null_async(async_desc_t** desc)
+{
+       error_t e;
+       syscall_desc_t* sysdesc;
+       if (e = get_all_desc(desc, &sysdesc))
+               return e;
+       return sys_null_async(sysdesc);
+}
+
+void cache_buster(uint32_t num_writes, uint32_t num_pages, uint32_t flags)
+{
+       sys_cache_buster(num_writes, num_pages, flags);
+}
+
+error_t cache_buster_async(async_desc_t** desc, uint32_t num_writes,
+                           uint32_t num_pages, uint32_t flags)
+{
+       error_t e;
+       syscall_desc_t* sysdesc;
+       if (e = get_all_desc(desc, &sysdesc))
+               return e;
+       return sys_cache_buster_async(sysdesc, num_writes, num_pages, flags);
+}
+
+uint32_t getcpuid(void)
+{
+       return sys_getcpuid();
+}