Moved Ivy lock tracking into per cpu info
authorZach Anderson <zra@zra-intrepid.(none)>
Fri, 18 Sep 2009 03:17:48 +0000 (20:17 -0700)
committerZach Anderson <zra@zra-intrepid.(none)>
Fri, 18 Sep 2009 03:17:48 +0000 (20:17 -0700)
kern/include/env.h
kern/include/ivy/sharc.h
kern/include/smp.h
kern/ivy/sharc.c
kern/src/env.c
kern/src/init.c

index 53151a9..10abc2a 100644 (file)
@@ -40,9 +40,6 @@ typedef int32_t envid_t;
 #define ENVX(envid)            ((envid) & (NENV - 1))
 
 // TODO: clean this up.
-#ifdef __SHARC__
-typedef sharC_env_t;
-#endif
 struct Env {
        TAILQ_ENTRY(Env) proc_link NOINIT;      // Free list link pointers
        spinlock_t proc_lock;
@@ -62,12 +59,6 @@ struct Env {
        uint32_t vcoremap[MAX_NUM_CPUS];
        uint32_t num_vcores;
 
-#ifdef __SHARC__
-       // held spin-locks
-       // zra: Used by Ivy. Let me know if this should go elsewhere.
-       sharC_env_t sharC_env;
-#endif
-
        // Address space
        pde_t *COUNT(NPDENTRIES) env_pgdir;                     // Kernel virtual address of page dir
        physaddr_t env_cr3;                     // Physical address of page dir
index 5ddfc26..4a61f1c 100644 (file)
@@ -23,8 +23,10 @@ typedef struct __ivy_sharC_thread {
     unsigned int max_lock;
 } sharC_env_t;
 
-#include <env.h>
+#include <smp.h>
+#include <process.h>
 
+extern int booting;
 extern int __ivy_checking_on;
 
 #pragma cilnoremove("sharC_env_init")
@@ -37,17 +39,35 @@ WRITES(sharC_env->max_lock,sharC_env->held_locks)
        return;
 }
 
+static __attribute__((always_inline)) int
+is_single_threaded() TRUSTED
+{
+       return booting || (num_idlecores == num_cpus - 1);
+}
+
+extern void sasmlinkage
+__sharc_single_thread_error_mayreturn(const char *msg);
+
+extern void sasmlinkage snoreturn
+__sharc_single_thread_error_noreturn(const char *msg);
+
+#ifdef IVY_FAST_CHECKS
+#define __sharc_single_thread_error __sharc_single_thread_error_noreturn
+#else
+#define __sharc_single_thread_error __sharc_single_thread_error_mayreturn
+#endif
+
 #pragma cilnoremove("__sharc_single_threaded")
 static SINLINE void __sharc_single_threaded(const void *msg) TRUSTED;
 static SINLINE void __sharc_single_threaded(const void *msg)
 {
-       // TODO: how do I know how many threads/cores are running?
-    //assert(1);
+       if (is_single_threaded()) return;
+       __sharc_single_thread_error(msg);
     return;
 }
 
-
-#define GET_SHARC_THREAD() current->sharC_env
+#define sharc_current      (&per_cpu_info[core_id()])
+#define GET_SHARC_THREAD() sharc_current->sharC_env
 
 #define THREAD_LOCKS(thread,i) (thread.held_locks[(i)])
 #define THREAD_MAX_LOCK(thread) (thread.max_lock)
@@ -90,7 +110,7 @@ static SINLINE void __sharc_add_lock(const void *lck)
 {
     unsigned int i;
 
-       if (!__ivy_checking_on || !current) return;
+       if (!__ivy_checking_on || is_single_threaded()) return;
 
     for (i = 0; i <= THIS_MAX_LOCK; i++)
         if (!THIS_LOCKS(i))
@@ -110,7 +130,7 @@ static SINLINE void __sharc_rm_lock(const void *lck)
 {
     unsigned int i;
 
-       if (!__ivy_checking_on || !current) return;
+       if (!__ivy_checking_on || is_single_threaded()) return;
 
     for (i = 0; i <= THIS_MAX_LOCK; i++)
         if (THIS_LOCKS(i) == lck)
@@ -136,7 +156,7 @@ __sharc_chk_lock(const void *lck, const void *what, unsigned int sz,
        // TODO: how do I find how many threads are running?
     //if (__sharc_num_threads == 1) return;
 
-       if (!__ivy_checking_on || !current) return;
+       if (!__ivy_checking_on || is_single_threaded()) return;
 
     for (i = 0; i <= THIS_MAX_LOCK; i++)
         if (THIS_LOCKS(i) == lck)
@@ -155,7 +175,7 @@ static SINLINE void
 __sharc_coerce_lock(const void *dstlck, const void *srclck,
                     const char *msg)
 {
-       if (!__ivy_checking_on) return;
+       if (!__ivy_checking_on || is_single_threaded()) return;
 
     if (dstlck != srclck)
         __sharc_lock_coerce_error(dstlck,srclck,msg);
index 5d46162..0a77e13 100644 (file)
 #include <workqueue.h>
 #include <env.h>
 
+#ifdef __SHARC__
+typedef sharC_env_t;
+#endif
 // will want this padded out to cacheline alignment
 struct per_cpu_info {
        spinlock_t lock;
        bool preempt_pending;
        struct workqueue NTPTV(t) workqueue;
+
+#ifdef __SHARC__
+       // held spin-locks. this will have to go elsewhere if multiple kernel
+       // threads can share a CPU.
+       // zra: Used by Ivy. Let me know if this should go elsewhere.
+       sharC_env_t sharC_env;
+#endif
+
 #ifdef __i386__
        spinlock_t amsg_lock;
        unsigned LCKD(&amsg_lock) amsg_current;
index 4f707ef..6b6f4cb 100644 (file)
@@ -3,7 +3,16 @@
 
 int __ivy_checking_on = 1;
 
-void __sharc_lock_error(const void *lck, const void *what,
+void __sharc_single_thread_error_mayreturn(const char *msg)
+{
+       int old;
+       if (!__ivy_checking_on) return;
+       old = __ivy_checking_on;
+       warn("Ivy: Not single threaded: %s\n", msg);
+       __ivy_checking_on = old;
+}
+
+void __sharc_lock_error_mayreturn(const void *lck, const void *what,
                         unsigned int sz, char *msg)
 {
        int old;
@@ -15,7 +24,7 @@ void __sharc_lock_error(const void *lck, const void *what,
        __ivy_checking_on = old;
 }
 
-void __sharc_lock_coerce_error(void *dstlck, void *srclck, char *msg)
+void __sharc_lock_coerce_error_mayreturn(void *dstlck, void *srclck, char *msg)
 {
        int old;
        if (!__ivy_checking_on) return;
index 33131d1..8b79f47 100644 (file)
@@ -279,10 +279,6 @@ env_alloc(env_t **newenv_store, envid_t parent_id)
        e->env_refcnt = 1;
        e->env_flags = 0;
        e->env_entry = 0; // cheating.  this really gets set in load_icode
-#ifdef __SHARC__
-       /* init SharC state */
-       sharC_env_init(&e->sharC_env);
-#endif
        e->num_vcores = 0;
        memset(&e->vcoremap, 0, sizeof(e->vcoremap));
 
index 57cfd8a..7f93e1b 100644 (file)
@@ -35,6 +35,9 @@
 #include <arch/ioapic.h>
 #endif
 
+// zra: flag for Ivy
+int booting = 1;
+
 void kernel_init(multiboot_info_t *mboot_info)
 {
        extern char (RO BND(__this, end) edata)[], (RO SNT end)[];
@@ -100,6 +103,9 @@ void kernel_init(multiboot_info_t *mboot_info)
        ne2k_init();
        #endif // __NETWORK__
 
+       // zra: let's Ivy know we're done booting
+       booting = 0;
+
        manager();
 }