make hlt start at 0x2000
[akaros.git] / kern / include / atomic.h
index 2f7ce24..dbe2c68 100644 (file)
@@ -41,29 +41,69 @@ extern inline bool atomic_sub_and_test(atomic_t *number, long val);
 /* Spin locks */
 struct spinlock {
        volatile uint32_t RACY rlock;
-#ifdef __CONFIG_SPINLOCK_DEBUG__
-       void *call_site;        
+#ifdef CONFIG_SPINLOCK_DEBUG
+       uintptr_t call_site;
        uint32_t calling_core;
+       bool irq_okay;
 #endif
 };
 typedef struct spinlock spinlock_t;
 #define SPINLOCK_INITIALIZER {0}
 
-extern inline void spinlock_init(spinlock_t *lock);
+#ifdef CONFIG_SPINLOCK_DEBUG
+#define SPINLOCK_INITIALIZER_IRQSAVE {0, .irq_okay = TRUE}
+#else
+#define SPINLOCK_INITIALIZER_IRQSAVE SPINLOCK_INITIALIZER
+#endif
+
+/* Arch dependent helpers/funcs: */
+extern inline void __spinlock_init(spinlock_t *lock);
 extern inline bool spin_locked(spinlock_t *lock);
-extern inline void spin_lock(spinlock_t *lock);
-extern inline void spin_unlock(spinlock_t *lock);
-extern inline void spinlock_debug(spinlock_t *lock);
+extern inline void __spin_lock(spinlock_t *lock);
+extern inline void __spin_unlock(spinlock_t *lock);
+
+/* So we can inline a __spin_lock if we want.  Even though we don't need this
+ * if we're debugging, its helpful to keep the include at the same place for
+ * all builds. */
+#include <arch/atomic.h>
+
+#ifdef CONFIG_SPINLOCK_DEBUG
+/* Arch indep, in k/s/atomic.c */
+void spin_lock(spinlock_t *lock);
+bool spin_trylock(spinlock_t *lock);
+void spin_unlock(spinlock_t *lock);
+void spinlock_debug(spinlock_t *lock);
+
+#else
+/* Just inline the arch-specific __ versions */
+static inline void spin_lock(spinlock_t *lock)
+{
+       __spin_lock(lock);
+}
+
+static inline bool spin_trylock(spinlock_t *lock)
+{
+       return __spin_trylock(lock);
+}
+
+static inline void spin_unlock(spinlock_t *lock)
+{
+       __spin_unlock(lock);
+}
 
+static inline void spinlock_debug(spinlock_t *lock)
+{
+}
+
+#endif /* CONFIG_SPINLOCK_DEBUG */
+
+/* Inlines, defined below */
+static inline void spinlock_init(spinlock_t *lock);
+static inline void spinlock_init_irqsave(spinlock_t *lock);
 static inline void spin_lock_irqsave(spinlock_t *lock);
 static inline void spin_unlock_irqsave(spinlock_t *lock);
 static inline bool spin_lock_irq_enabled(spinlock_t *lock);
 
-/* Used for spinlock debugging.  When we move spinlocks into .c, we can move
- * these too */
-void increase_lock_depth(uint32_t coreid);
-void decrease_lock_depth(uint32_t coreid);
-
 /* Hash locks (array of spinlocks).  Most all users will want the default one,
  * so point your pointer to one of them, though you could always kmalloc a
  * bigger one.  In the future, they might be growable, etc, which init code may
@@ -79,6 +119,7 @@ struct small_hashlock {
 };
 
 void hashlock_init(struct hashlock *hl, unsigned int nr_entries);
+void hashlock_init_irqsave(struct hashlock *hl, unsigned int nr_entries);
 void hash_lock(struct hashlock *hl, long key);
 void hash_unlock(struct hashlock *hl, long key);
 void hash_lock_irqsave(struct hashlock *hl, long key);
@@ -150,7 +191,8 @@ typedef struct checklist RACY checklist_t;
 #define ZEROS_ARRAY(size) {[0 ... ((size)-1)] 0}
 
 #define DEFAULT_CHECKLIST_MASK(sz) {(sz), ZEROS_ARRAY(BYTES_FOR_BITMASK(sz))}
-#define DEFAULT_CHECKLIST(sz) {SPINLOCK_INITIALIZER, DEFAULT_CHECKLIST_MASK(sz)}
+#define DEFAULT_CHECKLIST(sz) {SPINLOCK_INITIALIZER_IRQSAVE,                   \
+                               DEFAULT_CHECKLIST_MASK(sz)}
 #define INIT_CHECKLIST(nm, sz) \
        checklist_t nm = DEFAULT_CHECKLIST(sz);
 #define INIT_CHECKLIST_MASK(nm, sz)    \
@@ -192,6 +234,26 @@ void waiton_barrier(barrier_t* barrier);
 /* Spinlock bit flags */
 #define SPINLOCK_IRQ_EN                        0x80000000
 
+static inline void spinlock_init(spinlock_t *lock)
+{
+       __spinlock_init(lock);
+#ifdef CONFIG_SPINLOCK_DEBUG
+       lock->call_site = 0;
+       lock->calling_core = 0;
+       lock->irq_okay = FALSE;
+#endif
+}
+
+static inline void spinlock_init_irqsave(spinlock_t *lock)
+{
+       __spinlock_init(lock);
+#ifdef CONFIG_SPINLOCK_DEBUG
+       lock->call_site = 0;
+       lock->calling_core = 0;
+       lock->irq_okay = TRUE;
+#endif
+}
+
 // If ints are enabled, disable them and note it in the top bit of the lock
 // There is an assumption about releasing locks in order here...
 static inline void spin_lock_irqsave(spinlock_t *SAFE lock)
@@ -228,7 +290,7 @@ static inline bool spin_lock_irq_enabled(spinlock_t *SAFE lock)
  * concurrent write. */
 static inline void __seq_start_write(seq_ctr_t *seq_ctr)
 {
-#ifdef _CONFIG_SEQLOCK_DEBUG_
+#ifdef CONFIG_SEQLOCK_DEBUG
        assert(*seq_ctr % 2 == 0);
 #endif
        (*seq_ctr)++;
@@ -239,7 +301,7 @@ static inline void __seq_start_write(seq_ctr_t *seq_ctr)
 
 static inline void __seq_end_write(seq_ctr_t *seq_ctr)
 {
-#ifdef _CONFIG_SEQLOCK_DEBUG_
+#ifdef CONFIG_SEQLOCK_DEBUG
        assert(*seq_ctr % 2 == 1);
 #endif
        /* Need to prevent the compiler (and some arches) from reordering older