Add multiple arch support (alpha, intel, powerpc)
[urcu.git] / formal-model / urcu-controldataflow / urcu.spin
index 37518685f9360802f5dd405d816c20b389760d5b..dd5d17d32b33cbad437caae1ab2da8c9dffdc842 100644 (file)
  * Nested calls are not supported.
  */
 
+/*
+ * Only Alpha has out-of-order cache bank loads. Other architectures (intel,
+ * powerpc, arm) ensure that dependent reads won't be reordered. c.f.
+ * http://www.linuxjournal.com/article/8212)
+#ifdef ARCH_ALPHA
+#define HAVE_OOO_CACHE_READ
+#endif
+
 /*
  * Each process have its own data in cache. Caches are randomly updated.
  * smp_wmb and smp_rmb forces cache updates (write and read), smp_mb forces
@@ -206,7 +214,7 @@ typedef per_proc_bitfield {
        fi;
 
 /* Must consume all prior read tokens. All subsequent reads depend on it. */
-inline smp_rmb(i, j)
+inline smp_rmb(i)
 {
        atomic {
                CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
@@ -229,7 +237,7 @@ inline smp_rmb(i, j)
 }
 
 /* Must consume all prior write tokens. All subsequent writes depend on it. */
-inline smp_wmb(i, j)
+inline smp_wmb(i)
 {
        atomic {
                CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
@@ -253,11 +261,11 @@ inline smp_wmb(i, j)
 
 /* Synchronization point. Must consume all prior read and write tokens. All
  * subsequent reads and writes depend on it. */
-inline smp_mb(i, j)
+inline smp_mb(i)
 {
        atomic {
-               smp_wmb(i, j);
-               smp_rmb(i, j);
+               smp_wmb(i);
+               smp_rmb(i);
        }
 }
 
@@ -284,28 +292,29 @@ inline smp_mb_recv(i, j)
 {
        do
        :: (reader_barrier[get_readerid()] == 1) ->
-               smp_mb(i, j);
+               /*
+                * We choose to ignore cycles caused by writer busy-looping,
+                * waiting for the reader, sending barrier requests, and the
+                * reader always services them without continuing execution.
+                */
+progress_ignoring_mb1:
+               smp_mb(i);
                reader_barrier[get_readerid()] = 0;
        :: 1 ->
-               /* We choose to ignore writer's non-progress caused from the
-                * reader ignoring the writer's mb() requests */
-#ifdef WRITER_PROGRESS
-progress_writer_from_reader:
-#endif
+               /*
+                * We choose to ignore writer's non-progress caused by the
+                * reader ignoring the writer's mb() requests.
+                */
+progress_ignoring_mb2:
                break;
        od;
 }
 
-#ifdef WRITER_PROGRESS
-//#define PROGRESS_LABEL(progressid)   progress_writer_progid_##progressid:
-#define PROGRESS_LABEL(progressid)
-#else
-#define PROGRESS_LABEL(progressid)
-#endif
+#define PROGRESS_LABEL(progressid)     progress_writer_progid_##progressid:
 
 #define smp_mb_send(i, j, progressid)                                          \
 {                                                                              \
-       smp_mb(i, j);                                                           \
+       smp_mb(i);                                                              \
        i = 0;                                                                  \
        do                                                                      \
        :: i < NR_READERS ->                                                    \
@@ -315,22 +324,23 @@ progress_writer_from_reader:
                 * interest, given the reader has the ability to totally ignore \
                 * barrier requests.                                            \
                 */                                                             \
-PROGRESS_LABEL(progressid)                                                     \
                do                                                              \
-               :: (reader_barrier[i] == 1) -> skip;                            \
+               :: (reader_barrier[i] == 1) ->                                  \
+PROGRESS_LABEL(progressid)                                                     \
+                       skip;                                                   \
                :: (reader_barrier[i] == 0) -> break;                           \
                od;                                                             \
                i++;                                                            \
        :: i >= NR_READERS ->                                                   \
                break                                                           \
        od;                                                                     \
-       smp_mb(i, j);                                                           \
+       smp_mb(i);                                                              \
 }
 
 #else
 
-#define smp_mb_send(i, j, progressid)  smp_mb(i, j)
-#define smp_mb_reader  smp_mb
+#define smp_mb_send(i, j, progressid)  smp_mb(i)
+#define smp_mb_reader  smp_mb(i)
 #define smp_mb_recv(i, j)
 
 #endif
@@ -386,6 +396,7 @@ inline ooo_mem(i)
                        i++
                :: i >= SLAB_SIZE -> break
                od;
+#ifdef HAVE_OOO_CACHE_READ
                RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
                i = 0;
                do
@@ -403,6 +414,9 @@ inline ooo_mem(i)
                        i++
                :: i >= SLAB_SIZE -> break
                od;
+#else
+               smp_rmb(i);
+#endif /* HAVE_OOO_CACHE_READ */
        }
 }
 
@@ -641,7 +655,6 @@ non_atomic3_end:
                                        skip;
                                fi;
                        }
-               :: 1 -> skip;
                fi;
 
                goto non_atomic3_skip;
@@ -810,14 +823,14 @@ rmb2_end:
        goto end;
 rmb1:
 #ifndef NO_RMB
-       smp_rmb(i, j);
+       smp_rmb(i);
 #else
        ooo_mem(i);
 #endif
        goto rmb1_end;
 rmb2:
 #ifndef NO_RMB
-       smp_rmb(i, j);
+       smp_rmb(i);
 #else
        ooo_mem(i);
 #endif
@@ -968,7 +981,7 @@ progress_writer1:
                :: CONSUME_TOKENS(proc_urcu_writer,
                                  WRITE_DATA,
                                  WRITE_PROC_WMB) ->
-                       smp_wmb(i, j);
+                       smp_wmb(i);
                        PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
 
                :: CONSUME_TOKENS(proc_urcu_writer,
@@ -1151,6 +1164,12 @@ end_writer:
        :: 1 ->
 #ifdef WRITER_PROGRESS
 progress_writer2:
+#endif
+#ifdef READER_PROGRESS
+               /*
+                * Make sure we don't block the reader's progress.
+                */
+               smp_mb_send(i, j, 5);
 #endif
                skip;
        od;
This page took 0.024557 seconds and 4 git commands to generate.