Syscall debugging helper
[akaros.git] / kern / include / ivy / sharc.h
index 2b4274b..4a61f1c 100644 (file)
@@ -1,17 +1,32 @@
 #include <assert.h>
 #include <string.h>
 
-#define SINLINE inline
+#ifdef IVY_FAST_CHECKS
+  #define SINLINE __attribute__((always_inline))
+#else
+  #define SINLINE inline
+#endif
+
 #define SUNUSED __attribute__((unused))
 
+#ifndef sasmlinkage
+#define sasmlinkage __attribute__((regparm(0)))
+#endif
+
+#ifndef snoreturn
+#define snoreturn __attribute__((noreturn))
+#endif
+
 typedef struct __ivy_sharC_thread {
 #define SHARC_MAX_LOCKS 16
-    void *held_locks[SHARC_MAX_LOCKS];
+    const void *held_locks[SHARC_MAX_LOCKS];
     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")
@@ -24,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(void *msg) TRUSTED;
-static SINLINE void __sharc_single_threaded(void *msg)
+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)
@@ -46,21 +79,38 @@ static SINLINE void __sharc_single_threaded(void *msg)
  * Locks
  */
 
-extern void
-__sharc_lock_error(const void *lck, const void *what,
-                   unsigned int sz, char *msg);
+extern void sasmlinkage snoreturn
+__sharc_lock_error_noreturn(const void *lck, const void *what,
+                            unsigned int sz, const char *msg);
+
+extern void sasmlinkage
+__sharc_lock_error_mayreturn(const void *lck, const void *what,
+                             unsigned int sz, const char *msg);
 
-extern void
-__sharc_lock_coerce_error(void *dstlck, void *srclck, char *msg);
+extern void sasmlinkage snoreturn
+__sharc_lock_coerce_error_noreturn(const void *dstlck, const void *srclck,
+                                   const char *msg);
+
+extern void sasmlinkage
+__sharc_lock_coerce_error_mayreturn(const void *dstlck, const void *srclck,
+                                    const char *msg);
+
+#ifdef IVY_FAST_CHECKS
+#define __sharc_lock_error         __sharc_lock_error_noreturn
+#define __sharc_lock_coerce_error  __sharc_lock_coerce_error_noreturn
+#else
+#define __sharc_lock_error         __sharc_lock_error_mayreturn
+#define __sharc_lock_coerce_error  __sharc_lock_coerce_error_mayreturn
+#endif
 
 /* assumes no double-locking */
 #pragma cilnoremove("__sharc_add_lock")
-static SINLINE void __sharc_add_lock(void *lck) TRUSTED;
-static SINLINE void __sharc_add_lock(void *lck)
+static SINLINE void __sharc_add_lock(const void *lck) TRUSTED;
+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))
@@ -75,12 +125,12 @@ static SINLINE void __sharc_add_lock(void *lck)
 
 /* this will be very inefficient if the lock isn't actually held */
 #pragma cilnoremove("__sharc_rm_lock")
-static SINLINE void __sharc_rm_lock(void *lck) TRUSTED;
-static SINLINE void __sharc_rm_lock(void *lck)
+static SINLINE void __sharc_rm_lock(const void *lck) TRUSTED;
+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)
@@ -95,16 +145,18 @@ static SINLINE void __sharc_rm_lock(void *lck)
 
 #pragma cilnoremove("__sharc_chk_lock")
 static SINLINE void
-__sharc_chk_lock(void *lck, void *what, unsigned int sz, char *msg) TRUSTED;
+__sharc_chk_lock(const void *lck, const void *what, unsigned int sz,
+                 const char *msg) TRUSTED;
 static SINLINE void
-__sharc_chk_lock(void *lck, void *what, unsigned int sz, char *msg)
+__sharc_chk_lock(const void *lck, const void *what, unsigned int sz,
+                 const char *msg)
 {
     unsigned int i;
 
        // 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)
@@ -117,11 +169,13 @@ __sharc_chk_lock(void *lck, void *what, unsigned int sz, char *msg)
 
 #pragma cilnoremove("__sharc_coerce_lock")
 static SINLINE void
-__sharc_coerce_lock(void *dstlck, void *srclck, char *msg) TRUSTED;
+__sharc_coerce_lock(const void *dstlck, const void *srclck,
+                    const char *msg) TRUSTED;
 static SINLINE void
-__sharc_coerce_lock(void *dstlck, void *srclck, char *msg)
+__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);