- ooo_mem(i);
- atomic {
- old_gen = READ_CACHED_VAR(generation_ptr);
- WRITE_CACHED_VAR(generation_ptr, old_gen + 1);
- }
- ooo_mem(i);
-
- smp_mb(i);
- ooo_mem(i);
- tmp = READ_CACHED_VAR(urcu_gp_ctr);
- ooo_mem(i);
- WRITE_CACHED_VAR(urcu_gp_ctr, tmp ^ RCU_GP_CTR_BIT);
- ooo_mem(i);
- //smp_mc(i);
- wait_for_quiescent_state(tmp, i, j);
- //smp_mc(i);
- ooo_mem(i);
- tmp = READ_CACHED_VAR(urcu_gp_ctr);
- ooo_mem(i);
- WRITE_CACHED_VAR(urcu_gp_ctr, tmp ^ RCU_GP_CTR_BIT);
- //smp_mc(i);
- ooo_mem(i);
- wait_for_quiescent_state(tmp, i, j);
- ooo_mem(i);
- smp_mb(i);
- /* free-up step, e.g., kfree(). */
- ooo_mem(i);
+ do
+ :: (READ_CACHED_VAR(generation_ptr) < 5) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+ ooo_mem(i);
+ dispatch_sighand_write_exec();
+ atomic {
+ old_gen = READ_CACHED_VAR(generation_ptr);
+ WRITE_CACHED_VAR(generation_ptr, old_gen + 1);
+ }
+ ooo_mem(i);
+ dispatch_sighand_write_exec();
+
+ do
+ :: 1 ->
+ atomic {
+ if
+ :: write_lock == 0 ->
+ write_lock = 1;
+ break;
+ :: else ->
+ skip;
+ fi;
+ }
+ od;
+ smp_mb_writer(i, j);
+ dispatch_sighand_write_exec();
+ tmp = READ_CACHED_VAR(urcu_gp_ctr);
+ ooo_mem(i);
+ dispatch_sighand_write_exec();
+ WRITE_CACHED_VAR(urcu_gp_ctr, tmp ^ RCU_GP_CTR_BIT);
+ ooo_mem(i);
+ dispatch_sighand_write_exec();
+ //smp_mc(i);
+ wait_for_quiescent_state(tmp, tmp2, i, j);
+ //smp_mc(i);
+#ifndef SINGLE_FLIP
+ ooo_mem(i);
+ dispatch_sighand_write_exec();
+ tmp = READ_CACHED_VAR(urcu_gp_ctr);
+ ooo_mem(i);
+ dispatch_sighand_write_exec();
+ WRITE_CACHED_VAR(urcu_gp_ctr, tmp ^ RCU_GP_CTR_BIT);
+ //smp_mc(i);
+ ooo_mem(i);
+ dispatch_sighand_write_exec();
+ wait_for_quiescent_state(tmp, tmp2, i, j);
+#endif
+ smp_mb_writer(i, j);
+ dispatch_sighand_write_exec();
+ write_lock = 0;
+ /* free-up step, e.g., kfree(). */
+ atomic {
+ last_free_gen = old_gen;
+ free_done = 1;
+ }
+ :: else -> break;
+ od;
+ /*
+ * Given the reader loops infinitely, let the writer also busy-loop
+ * with progress here so, with weak fairness, we can test the
+ * writer's progress.
+ */
+end_writer:
+ do
+ :: 1 ->
+#ifdef WRITER_PROGRESS
+progress_writer2:
+#endif
+ dispatch_sighand_write_exec();
+ od;
+}
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+ byte i, j;
+