Fixes compilation issues for sparc
[akaros.git] / kern / include / atomic.h
index 3825236..898547f 100644 (file)
@@ -28,6 +28,18 @@ static inline void write_sequnlock(seqlock_t *lock);
 static inline seq_ctr_t read_seqbegin(seqlock_t *lock);
 static inline bool read_seqretry(seqlock_t *lock, seq_ctr_t ctr);
 
+#define MAX_SPINS 1000000000
+
+/* Will spin for a little while, but not deadlock if it never happens */
+#define spin_on(x)                                                             \
+       for (int i = 0; (x); i++) {                                                \
+               cpu_relax();                                                           \
+               if (i == MAX_SPINS) {                                                  \
+                       printk("Probably timed out/failed.\n");                            \
+                       break;                                                             \
+               }                                                                      \
+       }
+
 /*********************** Checklist stuff **********************/
 typedef struct checklist_mask {
        // only need an uint8_t, but we need the bits[] to be word aligned
@@ -129,6 +141,9 @@ static inline void __seq_start_write(seq_ctr_t *seq_ctr)
        assert(*seq_ctr % 2 == 0);
 #endif
        (*seq_ctr)++;
+       /* We're the only writer, so we need to prevent the compiler (and some
+        * arches) from reordering writes before this point. */
+       wmb();
 }
 
 static inline void __seq_end_write(seq_ctr_t *seq_ctr)
@@ -136,6 +151,9 @@ static inline void __seq_end_write(seq_ctr_t *seq_ctr)
 #ifdef _CONFIG_SEQLOCK_DEBUG_
        assert(*seq_ctr % 2 == 1);
 #endif
+       /* Need to prevent the compiler (and some arches) from reordering older
+        * stores */
+       wmb();
        (*seq_ctr)++;
 }