}
}
-
#ifdef REMOTE_BARRIERS
bit reader_barrier[NR_READERS];
:: (reader_barrier[get_readerid()] == 1) ->
smp_mb(i, j);
reader_barrier[get_readerid()] = 0;
- :: 1 -> skip;
+ :: 1 ->
+ /*
+ * Busy-looping waiting for other barrier requests are not considered as
+ * non-progress.
+ */
+#ifdef READER_PROGRESS
+progress_reader2:
+#endif
+ skip;
:: 1 -> break;
od;
}
-inline smp_mb_send(i, j)
-{
- smp_mb(i, j);
- i = 0;
- do
- :: i < NR_READERS ->
- reader_barrier[i] = 1;
- do
- :: (reader_barrier[i] == 1) -> skip;
- :: (reader_barrier[i] == 0) -> break;
- od;
- i++;
- :: i >= NR_READERS ->
- break
- od;
- smp_mb(i, j);
+#ifdef WRITER_PROGRESS
+#define PROGRESS_LABEL(progressid) progress_writer_progid_##progressid:
+#else
+#define PROGRESS_LABEL(progressid)
+#endif
+
+#define smp_mb_send(i, j, progressid) \
+{ \
+ smp_mb(i, j); \
+ i = 0; \
+ do \
+ :: i < NR_READERS -> \
+ reader_barrier[i] = 1; \
+ do \
+ :: (reader_barrier[i] == 1) -> \
+ /* \
+ * Busy-looping waiting for reader barrier handling is of little\
+ * interest, given the reader has the ability to totally ignore \
+ * barrier requests. \
+ */ \
+PROGRESS_LABEL(progressid) \
+ skip; \
+ :: (reader_barrier[i] == 0) -> break; \
+ od; \
+ i++; \
+ :: i >= NR_READERS -> \
+ break \
+ od; \
+ smp_mb(i, j); \
}
#else
-#define smp_mb_send smp_mb
+#define smp_mb_send(i, j, progressid) smp_mb(i, j)
#define smp_mb_reader smp_mb
#define smp_mb_recv(i, j)
PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT);
+ /* For single flip, we need to know the current parity */
+ cur_gp_val = cur_gp_val ^ RCU_GP_CTR_BIT;
#endif
do :: 1 ->
ooo_mem(i);
/* ONLY WAITING FOR READER 0 */
tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
- cur_gp_val = cur_gp_val ^ RCU_GP_CTR_BIT;
+#ifndef SINGLE_FLIP
+ /* In normal execution, we are always starting by
+ * waiting for the even parity.
+ */
+ cur_gp_val = RCU_GP_CTR_BIT;
+#endif
if
:: (tmp2 & RCU_GP_CTR_NEST_MASK)
&& ((tmp2 ^ cur_gp_val) & RCU_GP_CTR_BIT) ->
ooo_mem(i);
/* ONLY WAITING FOR READER 0 */
tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
- cur_gp_val = cur_gp_val ^ RCU_GP_CTR_BIT;
if
:: (tmp2 & RCU_GP_CTR_NEST_MASK)
- && ((tmp2 ^ cur_gp_val) & RCU_GP_CTR_BIT) ->
+ && ((tmp2 ^ 0) & RCU_GP_CTR_BIT) ->
PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP);
:: else ->
PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT);
/* Non-atomic parts of the loop */
goto end;
smp_mb_send1:
- smp_mb_send(i, j);
+ smp_mb_send(i, j, 1);
goto smp_mb_send1_end;
#ifndef GEN_ERROR_WRITER_PROGRESS
smp_mb_send2:
- smp_mb_send(i, j);
+ smp_mb_send(i, j, 2);
goto smp_mb_send2_end;
smp_mb_send3:
- smp_mb_send(i, j);
+ smp_mb_send(i, j, 3);
goto smp_mb_send3_end;
#endif
smp_mb_send4:
- smp_mb_send(i, j);
+ smp_mb_send(i, j, 4);
goto smp_mb_send4_end;
end:
skip;